summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-11-15 10:10:41 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-11-15 10:10:41 -0500
commit2944f347d087ff24ec808e4b70fe104a772a97a0 (patch)
treea5de4fbefe16ef359a526442fb41251f123399d5
parent678b0b89572768b21d8b74360d55b75b233799c4 (diff)
parentd025f1e4dca8fc1436aff76f9e6185fe3e728daa (diff)
Fork of Original Code Base: anongit.freedesktop.org/systemd
This is the initial fork of the code base from freedsktop.org. The code is provided here as a reference of the initial starting point and for possible future checkouts after a large portion of this code is removed. Merge git://anongit.freedesktop.org/systemd/systemd
-rw-r--r--.dir-locals.el7
-rw-r--r--.gitignore144
-rw-r--r--.mailmap45
-rw-r--r--.vimrc4
-rw-r--r--CODING_STYLE27
-rw-r--r--DISTRO_PORTING58
-rw-r--r--LICENSE.GPL2339
-rw-r--r--LICENSE.LGPL2.1508
-rw-r--r--LICENSE.MIT19
-rw-r--r--Makefile.am4045
-rw-r--r--NEWS1149
-rw-r--r--TODO609
-rwxr-xr-xautogen.sh67
-rw-r--r--configure.ac881
-rw-r--r--docs/.gitignore1
l---------docs/Makefile1
-rw-r--r--docs/gudev/.gitignore19
-rw-r--r--docs/gudev/Makefile.am113
-rw-r--r--docs/gudev/gudev-docs.xml52
-rw-r--r--docs/gudev/gudev-sections.txt100
-rw-r--r--docs/gudev/gudev.types4
-rw-r--r--docs/gudev/version.xml.in1
-rw-r--r--docs/libudev/.gitignore19
-rw-r--r--docs/libudev/Makefile.am107
-rw-r--r--docs/libudev/libudev-docs.xml40
-rw-r--r--docs/libudev/libudev-sections.txt134
-rw-r--r--docs/libudev/libudev.types0
-rw-r--r--docs/libudev/version.xml.in1
-rw-r--r--docs/sysvinit/.gitignore1
l---------docs/sysvinit/Makefile1
-rw-r--r--docs/sysvinit/README.in27
-rw-r--r--docs/var-log/.gitignore1
l---------docs/var-log/Makefile1
-rw-r--r--docs/var-log/README.in26
-rw-r--r--hwdb/.gitignore3
-rw-r--r--hwdb/20-OUI.hwdb51108
-rw-r--r--hwdb/20-acpi-vendor.hwdb6050
-rw-r--r--hwdb/20-pci-classes.hwdb531
-rw-r--r--hwdb/20-pci-vendor-product.hwdb63618
-rw-r--r--hwdb/20-usb-classes.hwdb339
-rw-r--r--hwdb/20-usb-vendor-product.hwdb47304
-rwxr-xr-xhwdb/ids-update.pl239
-rw-r--r--introspect.awk13
-rw-r--r--keymaps-force-release/common-volume-keys3
-rw-r--r--keymaps-force-release/dell-touchpad1
-rw-r--r--keymaps-force-release/dell-xps1
-rw-r--r--keymaps-force-release/hp-other3
-rw-r--r--keymaps-force-release/samsung-90x3a6
-rw-r--r--keymaps-force-release/samsung-other10
-rw-r--r--keymaps/acer22
-rw-r--r--keymaps/acer-aspire_57205
-rw-r--r--keymaps/acer-aspire_5920g5
-rw-r--r--keymaps/acer-aspire_69205
-rw-r--r--keymaps/acer-aspire_89305
-rw-r--r--keymaps/acer-travelmate_c3005
-rw-r--r--keymaps/asus3
-rw-r--r--keymaps/compaq-e_evo4
-rw-r--r--keymaps/dell29
-rw-r--r--keymaps/dell-latitude-xt24
-rw-r--r--keymaps/everex-xt50007
-rw-r--r--keymaps/fujitsu-amilo_li_27323
-rw-r--r--keymaps/fujitsu-amilo_pa_25483
-rw-r--r--keymaps/fujitsu-amilo_pro_edition_v35054
-rw-r--r--keymaps/fujitsu-amilo_pro_v32052
-rw-r--r--keymaps/fujitsu-amilo_si_15206
-rw-r--r--keymaps/fujitsu-esprimo_mobile_v54
-rw-r--r--keymaps/fujitsu-esprimo_mobile_v62
-rw-r--r--keymaps/genius-slimstar-32035
-rw-r--r--keymaps/hewlett-packard12
-rw-r--r--keymaps/hewlett-packard-2510p_2530p2
-rw-r--r--keymaps/hewlett-packard-compaq_elitebook2
-rw-r--r--keymaps/hewlett-packard-pavilion3
-rw-r--r--keymaps/hewlett-packard-presario-21003
-rw-r--r--keymaps/hewlett-packard-tablet6
-rw-r--r--keymaps/hewlett-packard-tx23
-rw-r--r--keymaps/hewlett-packard_elitebook-8440p5
-rw-r--r--keymaps/ibm-thinkpad-usb-keyboard-trackpoint7
-rw-r--r--keymaps/inventec-symphony_6.0_7.02
-rw-r--r--keymaps/lenovo-30005
-rw-r--r--keymaps/lenovo-ideapad8
-rw-r--r--keymaps/lenovo-thinkpad-usb-keyboard-trackpoint13
-rw-r--r--keymaps/lenovo-thinkpad_x200_tablet6
-rw-r--r--keymaps/lenovo-thinkpad_x6_tablet8
-rw-r--r--keymaps/lg-x11012
-rw-r--r--keymaps/logitech-wave16
-rw-r--r--keymaps/logitech-wave-cordless15
-rw-r--r--keymaps/logitech-wave-pro-cordless12
-rw-r--r--keymaps/maxdata-pro_70009
-rw-r--r--keymaps/medion-fid20602
-rw-r--r--keymaps/medionnb-a5554
-rw-r--r--keymaps/micro-star13
-rw-r--r--keymaps/module-asus-w3j11
-rw-r--r--keymaps/module-ibm16
-rw-r--r--keymaps/module-lenovo17
-rw-r--r--keymaps/module-sony8
-rw-r--r--keymaps/module-sony-old2
-rw-r--r--keymaps/module-sony-vgn8
-rw-r--r--keymaps/module-sony-vpc4
-rw-r--r--keymaps/olpc-xo74
-rw-r--r--keymaps/onkyo14
-rw-r--r--keymaps/oqo-model25
-rw-r--r--keymaps/samsung-90x3a5
-rw-r--r--keymaps/samsung-other14
-rw-r--r--keymaps/samsung-sq1us7
-rw-r--r--keymaps/samsung-sx20s4
-rw-r--r--keymaps/toshiba-satellite_a1002
-rw-r--r--keymaps/toshiba-satellite_a11010
-rw-r--r--keymaps/toshiba-satellite_m30x6
-rw-r--r--keymaps/zepto-znote11
-rw-r--r--m4/.gitignore7
-rw-r--r--m4/acx_libwrap.m419
-rw-r--r--m4/attributes.m4288
-rwxr-xr-xmake-directive-index.py149
-rwxr-xr-xmake-man-index.py96
-rw-r--r--man/.gitignore1
l---------man/Makefile1
-rw-r--r--man/binfmt.d.xml124
-rw-r--r--man/bootup.xml226
-rw-r--r--man/crypttab.xml313
-rw-r--r--man/custom-html.xsl50
-rw-r--r--man/daemon.xml949
-rw-r--r--man/halt.xml172
-rw-r--r--man/hostname.xml102
-rw-r--r--man/hostnamectl.xml228
-rw-r--r--man/journalctl.xml533
-rw-r--r--man/journald.conf.xml411
-rw-r--r--man/kernel-command-line.xml295
-rw-r--r--man/locale.conf.xml149
-rw-r--r--man/localectl.xml259
-rw-r--r--man/localtime.xml103
-rw-r--r--man/loginctl.xml474
-rw-r--r--man/logind.conf.xml298
-rw-r--r--man/machine-id.xml145
-rw-r--r--man/machine-info.xml154
-rw-r--r--man/modules-load.d.xml120
-rw-r--r--man/os-release.xml350
-rw-r--r--man/pam_systemd.xml319
-rw-r--r--man/runlevel.xml154
-rw-r--r--man/sd-daemon.xml180
-rw-r--r--man/sd-id128.xml181
-rw-r--r--man/sd-journal.xml130
-rw-r--r--man/sd-login.xml146
-rw-r--r--man/sd-readahead.xml117
-rw-r--r--man/sd_booted.xml128
-rw-r--r--man/sd_get_seats.xml129
-rw-r--r--man/sd_id128_get_machine.xml138
-rw-r--r--man/sd_id128_randomize.xml118
-rw-r--r--man/sd_id128_to_string.xml131
-rw-r--r--man/sd_is_fifo.xml217
-rw-r--r--man/sd_journal_add_match.xml189
-rw-r--r--man/sd_journal_get_cursor.xml151
-rw-r--r--man/sd_journal_get_cutoff_realtime_usec.xml142
-rw-r--r--man/sd_journal_get_data.xml201
-rw-r--r--man/sd_journal_get_fd.xml272
-rw-r--r--man/sd_journal_get_realtime_usec.xml146
-rw-r--r--man/sd_journal_get_usage.xml104
-rw-r--r--man/sd_journal_next.xml214
-rw-r--r--man/sd_journal_open.xml184
-rw-r--r--man/sd_journal_print.xml251
-rw-r--r--man/sd_journal_query_unique.xml214
-rw-r--r--man/sd_journal_seek_head.xml178
-rw-r--r--man/sd_journal_stream_fd.xml171
-rw-r--r--man/sd_listen_fds.xml204
-rw-r--r--man/sd_login_monitor_new.xml173
-rw-r--r--man/sd_notify.xml319
-rw-r--r--man/sd_pid_get_session.xml160
-rw-r--r--man/sd_readahead.xml178
-rw-r--r--man/sd_seat_get_active.xml180
-rw-r--r--man/sd_session_is_active.xml240
-rw-r--r--man/sd_uid_get_state.xml190
-rw-r--r--man/shutdown.xml188
-rw-r--r--man/sysctl.d.xml127
-rw-r--r--man/systemctl.xml1268
-rw-r--r--man/systemd-analyze.xml138
-rw-r--r--man/systemd-ask-password-console.service.xml96
-rw-r--r--man/systemd-ask-password.xml183
-rw-r--r--man/systemd-binfmt.service.xml76
-rw-r--r--man/systemd-cat.xml205
-rw-r--r--man/systemd-cgls.xml141
-rw-r--r--man/systemd-cgtop.xml276
-rw-r--r--man/systemd-coredumpctl.xml214
-rw-r--r--man/systemd-cryptsetup-generator.xml147
-rw-r--r--man/systemd-cryptsetup@.service.xml87
-rw-r--r--man/systemd-delta.xml181
-rw-r--r--man/systemd-detect-virt.xml151
-rw-r--r--man/systemd-fsck@.service.xml110
-rw-r--r--man/systemd-fstab-generator.xml118
-rw-r--r--man/systemd-getty-generator.xml90
-rw-r--r--man/systemd-halt.service.xml119
-rw-r--r--man/systemd-hostnamed.service.xml87
-rw-r--r--man/systemd-inhibit.xml205
-rw-r--r--man/systemd-initctl.service.xml76
-rw-r--r--man/systemd-journald.service.xml173
-rw-r--r--man/systemd-localed.service.xml89
-rw-r--r--man/systemd-logind.service.xml133
-rw-r--r--man/systemd-machine-id-setup.xml132
-rw-r--r--man/systemd-modules-load.service.xml101
-rw-r--r--man/systemd-notify.xml218
-rw-r--r--man/systemd-nspawn.xml331
-rw-r--r--man/systemd-quotacheck.service.xml102
-rw-r--r--man/systemd-random-seed-load.service.xml80
-rw-r--r--man/systemd-readahead-replay.service.xml113
-rw-r--r--man/systemd-remount-fs.service.xml87
-rw-r--r--man/systemd-shutdownd.service.xml77
-rw-r--r--man/systemd-suspend.service.xml126
-rw-r--r--man/systemd-sysctl.service.xml78
-rw-r--r--man/systemd-system-update-generator.xml79
-rw-r--r--man/systemd-timedated.service.xml88
-rw-r--r--man/systemd-tmpfiles.xml162
-rw-r--r--man/systemd-tty-ask-password-agent.xml166
-rw-r--r--man/systemd-udevd.service.xml168
-rw-r--r--man/systemd-update-utmp-runlevel.service.xml76
-rw-r--r--man/systemd-user-sessions.service.xml77
-rw-r--r--man/systemd-vconsole-setup.service.xml118
-rw-r--r--man/systemd.automount.xml167
-rw-r--r--man/systemd.conf.xml284
-rw-r--r--man/systemd.device.xml168
-rw-r--r--man/systemd.exec.xml1154
-rw-r--r--man/systemd.journal-fields.xml450
-rw-r--r--man/systemd.kill.xml170
-rw-r--r--man/systemd.mount.xml282
-rw-r--r--man/systemd.path.xml220
-rw-r--r--man/systemd.preset.xml204
-rw-r--r--man/systemd.service.xml924
-rw-r--r--man/systemd.snapshot.xml87
-rw-r--r--man/systemd.socket.xml685
-rw-r--r--man/systemd.special.xml817
-rw-r--r--man/systemd.swap.xml213
-rw-r--r--man/systemd.target.xml108
-rw-r--r--man/systemd.timer.xml192
-rw-r--r--man/systemd.unit.xml1084
-rw-r--r--man/systemd.xml1272
-rw-r--r--man/telinit.xml195
-rw-r--r--man/timedatectl.xml293
-rw-r--r--man/tmpfiles.d.xml321
-rw-r--r--man/udev.xml705
-rw-r--r--man/udevadm.xml495
-rw-r--r--man/vconsole.conf.xml147
-rw-r--r--po/.gitignore5
-rw-r--r--po/POTFILES.in5
-rw-r--r--po/POTFILES.skip20
-rw-r--r--po/pl.po175
-rw-r--r--rules/.gitignore1
-rw-r--r--rules/42-usb-hid-pm.rules45
-rw-r--r--rules/50-udev-default.rules90
-rw-r--r--rules/60-cdrom_id.rules20
-rw-r--r--rules/60-persistent-alsa.rules14
-rw-r--r--rules/60-persistent-input.rules38
-rw-r--r--rules/60-persistent-serial.rules20
-rw-r--r--rules/60-persistent-storage-tape.rules25
-rw-r--r--rules/60-persistent-storage.rules89
-rw-r--r--rules/60-persistent-v4l.rules20
-rw-r--r--rules/61-accelerometer.rules3
-rw-r--r--rules/64-btrfs.rules13
-rw-r--r--rules/75-net-description.rules14
-rw-r--r--rules/75-probe_mtd.rules8
-rw-r--r--rules/75-tty-description.rules13
-rw-r--r--rules/78-sound-card.rules86
-rw-r--r--rules/80-drivers.rules12
-rw-r--r--rules/95-udev-late.rules4
-rw-r--r--rules/99-systemd.rules.in60
-rw-r--r--shell-completion/systemd-bash-completion.sh605
-rw-r--r--shell-completion/systemd-zsh-completion.zsh1023
-rw-r--r--src/.gitignore6
-rw-r--r--src/Makefile28
l---------src/ac-power/Makefile1
-rw-r--r--src/ac-power/ac-power.c111
l---------src/analyze/Makefile1
-rwxr-xr-xsrc/analyze/systemd-analyze294
l---------src/ask-password/Makefile1
-rw-r--r--src/ask-password/ask-password.c184
l---------src/binfmt/Makefile1
-rw-r--r--src/binfmt/binfmt.c170
l---------src/cgls/Makefile1
-rw-r--r--src/cgls/cgls.c182
l---------src/cgroups-agent/Makefile1
-rw-r--r--src/cgroups-agent/cgroups-agent.c101
l---------src/cgtop/Makefile1
-rw-r--r--src/cgtop/cgtop.c793
-rw-r--r--src/core/.gitignore6
l---------src/core/Makefile1
-rw-r--r--src/core/audit-fd.c73
-rw-r--r--src/core/audit-fd.h25
-rw-r--r--src/core/automount.c902
-rw-r--r--src/core/automount.h73
-rw-r--r--src/core/build.h84
-rw-r--r--src/core/bus-errors.h55
-rw-r--r--src/core/cgroup-attr.c102
-rw-r--r--src/core/cgroup-attr.h46
-rw-r--r--src/core/cgroup.c598
-rw-r--r--src/core/cgroup.h91
-rw-r--r--src/core/condition.c370
-rw-r--r--src/core/condition.h69
-rw-r--r--src/core/dbus-automount.c75
-rw-r--r--src/core/dbus-automount.h31
-rw-r--r--src/core/dbus-device.c68
-rw-r--r--src/core/dbus-device.h31
-rw-r--r--src/core/dbus-execute.c439
-rw-r--r--src/core/dbus-execute.h124
-rw-r--r--src/core/dbus-job.c378
-rw-r--r--src/core/dbus-job.h33
-rw-r--r--src/core/dbus-kill.c35
-rw-r--r--src/core/dbus-kill.h39
-rw-r--r--src/core/dbus-manager.c1685
-rw-r--r--src/core/dbus-manager.h28
-rw-r--r--src/core/dbus-mount.c168
-rw-r--r--src/core/dbus-mount.h31
-rw-r--r--src/core/dbus-path.c122
-rw-r--r--src/core/dbus-path.h32
-rw-r--r--src/core/dbus-service.c161
-rw-r--r--src/core/dbus-service.h31
-rw-r--r--src/core/dbus-snapshot.c94
-rw-r--r--src/core/dbus-snapshot.h30
-rw-r--r--src/core/dbus-socket.c151
-rw-r--r--src/core/dbus-socket.h31
-rw-r--r--src/core/dbus-swap.c115
-rw-r--r--src/core/dbus-swap.h32
-rw-r--r--src/core/dbus-target.c58
-rw-r--r--src/core/dbus-target.h30
-rw-r--r--src/core/dbus-timer.c140
-rw-r--r--src/core/dbus-timer.h31
-rw-r--r--src/core/dbus-unit.c887
-rw-r--r--src/core/dbus-unit.h147
-rw-r--r--src/core/dbus.c1479
-rw-r--r--src/core/dbus.h50
-rw-r--r--src/core/device.c644
-rw-r--r--src/core/device.h56
-rw-r--r--src/core/execute.c2132
-rw-r--r--src/core/execute.h209
-rw-r--r--src/core/fdset.c167
-rw-r--r--src/core/fdset.h37
-rw-r--r--src/core/hostname-setup.c182
-rw-r--r--src/core/hostname-setup.h24
-rw-r--r--src/core/ima-setup.c115
-rw-r--r--src/core/ima-setup.h26
-rw-r--r--src/core/initreq.h77
-rw-r--r--src/core/job.c1086
-rw-r--r--src/core/job.h230
-rw-r--r--src/core/kill.c63
-rw-r--r--src/core/kill.h60
-rw-r--r--src/core/killall.c177
-rw-r--r--src/core/killall.h27
-rw-r--r--src/core/kmod-setup.c104
-rw-r--r--src/core/kmod-setup.h24
-rw-r--r--src/core/load-dropin.c150
-rw-r--r--src/core/load-dropin.h28
-rw-r--r--src/core/load-fragment-gperf.gperf.m4255
-rw-r--r--src/core/load-fragment.c2541
-rw-r--r--src/core/load-fragment.h88
-rw-r--r--src/core/locale-setup.c241
-rw-r--r--src/core/locale-setup.h24
-rw-r--r--src/core/loopback-setup.c317
-rw-r--r--src/core/loopback-setup.h24
-rw-r--r--src/core/machine-id-setup.c246
-rw-r--r--src/core/machine-id-setup.h24
-rw-r--r--src/core/macros.systemd.in56
-rw-r--r--src/core/main.c1950
-rw-r--r--src/core/manager.c2309
-rw-r--r--src/core/manager.h293
-rw-r--r--src/core/mount-setup.c441
-rw-r--r--src/core/mount-setup.h33
-rw-r--r--src/core/mount.c1885
-rw-r--r--src/core/mount.h121
-rw-r--r--src/core/namespace.c330
-rw-r--r--src/core/namespace.h31
-rw-r--r--src/core/org.freedesktop.systemd1.conf92
-rw-r--r--src/core/org.freedesktop.systemd1.policy.in.in41
-rw-r--r--src/core/org.freedesktop.systemd1.service11
-rw-r--r--src/core/path.c773
-rw-r--r--src/core/path.h110
-rw-r--r--src/core/securebits.h45
-rw-r--r--src/core/selinux-access.c441
-rw-r--r--src/core/selinux-access.h62
-rw-r--r--src/core/selinux-setup.c123
-rw-r--r--src/core/selinux-setup.h26
-rw-r--r--src/core/service.c3941
-rw-r--r--src/core/service.h225
-rw-r--r--src/core/shutdown.c316
-rw-r--r--src/core/snapshot.c308
-rw-r--r--src/core/snapshot.h50
-rw-r--r--src/core/socket.c2289
-rw-r--r--src/core/socket.h175
-rw-r--r--src/core/special.h113
-rw-r--r--src/core/swap.c1433
-rw-r--r--src/core/swap.h121
-rw-r--r--src/core/switch-root.c142
-rw-r--r--src/core/switch-root.h27
-rw-r--r--src/core/syscall-list.c55
-rw-r--r--src/core/syscall-list.h30
-rw-r--r--src/core/sysfs-show.h24
-rw-r--r--src/core/system.conf43
-rw-r--r--src/core/systemd.pc.in23
-rw-r--r--src/core/target.c239
-rw-r--r--src/core/target.h44
-rw-r--r--src/core/tcpwrap.c68
-rw-r--r--src/core/tcpwrap.h26
-rw-r--r--src/core/timer.c519
-rw-r--r--src/core/timer.h90
-rw-r--r--src/core/transaction.c1087
-rw-r--r--src/core/transaction.h56
-rw-r--r--src/core/umount.c639
-rw-r--r--src/core/umount.h30
-rw-r--r--src/core/unit-printf.c346
-rw-r--r--src/core/unit-printf.h28
-rw-r--r--src/core/unit.c2738
-rw-r--r--src/core/unit.h551
-rw-r--r--src/core/user.conf17
l---------src/cryptsetup/Makefile1
-rw-r--r--src/cryptsetup/cryptsetup-generator.c449
-rw-r--r--src/cryptsetup/cryptsetup.c560
l---------src/delta/Makefile1
-rw-r--r--src/delta/delta.c490
l---------src/detect-virt/Makefile1
-rw-r--r--src/detect-virt/detect-virt.c172
l---------src/fsck/Makefile1
-rw-r--r--src/fsck/fsck.c407
l---------src/fstab-generator/Makefile1
-rw-r--r--src/fstab-generator/fstab-generator.c560
l---------src/getty-generator/Makefile1
-rw-r--r--src/getty-generator/getty-generator.c180
-rw-r--r--src/gudev/.gitignore7
l---------src/gudev/Makefile1
-rwxr-xr-xsrc/gudev/gjs-example.js75
-rw-r--r--src/gudev/gudev-1.0.pc.in11
-rw-r--r--src/gudev/gudev.h33
-rw-r--r--src/gudev/gudevclient.c527
-rw-r--r--src/gudev/gudevclient.h100
-rw-r--r--src/gudev/gudevdevice.c963
-rw-r--r--src/gudev/gudevdevice.h128
-rw-r--r--src/gudev/gudevenumerator.c431
-rw-r--r--src/gudev/gudevenumerator.h107
-rw-r--r--src/gudev/gudevenums.h49
-rw-r--r--src/gudev/gudevenumtypes.c.template39
-rw-r--r--src/gudev/gudevenumtypes.h.template24
-rw-r--r--src/gudev/gudevmarshal.list1
-rw-r--r--src/gudev/gudevprivate.h41
-rw-r--r--src/gudev/gudevtypes.h51
-rwxr-xr-xsrc/gudev/seed-example-enum.js38
-rwxr-xr-xsrc/gudev/seed-example.js72
-rw-r--r--src/hostname/.gitignore1
l---------src/hostname/Makefile1
-rw-r--r--src/hostname/hostnamectl.c546
-rw-r--r--src/hostname/hostnamed.c636
-rw-r--r--src/hostname/org.freedesktop.hostname1.conf27
-rw-r--r--src/hostname/org.freedesktop.hostname1.policy.in49
-rw-r--r--src/hostname/org.freedesktop.hostname1.service12
l---------src/initctl/Makefile1
-rw-r--r--src/initctl/initctl.c451
-rw-r--r--src/journal/.gitignore2
l---------src/journal/Makefile1
-rw-r--r--src/journal/browse.html544
-rw-r--r--src/journal/cat.c180
-rw-r--r--src/journal/compress.c208
-rw-r--r--src/journal/compress.h35
-rw-r--r--src/journal/coredump.c278
-rw-r--r--src/journal/coredumpctl.c583
-rw-r--r--src/journal/fsprg.c384
-rw-r--r--src/journal/fsprg.h64
-rw-r--r--src/journal/journal-authenticate.c563
-rw-r--r--src/journal/journal-authenticate.h44
-rw-r--r--src/journal/journal-def.h216
-rw-r--r--src/journal/journal-file.c2872
-rw-r--r--src/journal/journal-file.h193
-rw-r--r--src/journal/journal-gatewayd.c916
-rw-r--r--src/journal/journal-internal.h127
-rw-r--r--src/journal/journal-qrcode.c138
-rw-r--r--src/journal/journal-qrcode.h30
-rw-r--r--src/journal/journal-send.c608
-rw-r--r--src/journal/journal-vacuum.c318
-rw-r--r--src/journal/journal-vacuum.h26
-rw-r--r--src/journal/journal-verify.c1163
-rw-r--r--src/journal/journal-verify.h26
-rw-r--r--src/journal/journalctl.c1060
-rw-r--r--src/journal/journald-console.c86
-rw-r--r--src/journal/journald-console.h26
-rw-r--r--src/journal/journald-gperf.gperf39
-rw-r--r--src/journal/journald-kmsg.c438
-rw-r--r--src/journal/journald-kmsg.h32
-rw-r--r--src/journal/journald-native.c420
-rw-r--r--src/journal/journald-native.h30
-rw-r--r--src/journal/journald-rate-limit.c275
-rw-r--r--src/journal/journald-rate-limit.h31
-rw-r--r--src/journal/journald-server.c1502
-rw-r--r--src/journal/journald-server.h152
-rw-r--r--src/journal/journald-stream.c459
-rw-r--r--src/journal/journald-stream.h30
-rw-r--r--src/journal/journald-syslog.c492
-rw-r--r--src/journal/journald-syslog.h36
-rw-r--r--src/journal/journald.c140
-rw-r--r--src/journal/journald.conf32
-rw-r--r--src/journal/libsystemd-journal.pc.in19
-rw-r--r--src/journal/libsystemd-journal.sym87
-rw-r--r--src/journal/lookup3.c1009
-rw-r--r--src/journal/lookup3.h22
-rw-r--r--src/journal/mmap-cache.c577
-rw-r--r--src/journal/mmap-cache.h36
-rw-r--r--src/journal/sd-journal.c2391
-rw-r--r--src/journal/test-journal-enum.c53
-rw-r--r--src/journal/test-journal-match.c67
-rw-r--r--src/journal/test-journal-send.c78
-rw-r--r--src/journal/test-journal-stream.c185
-rw-r--r--src/journal/test-journal-syslog.c44
-rw-r--r--src/journal/test-journal-verify.c147
-rw-r--r--src/journal/test-journal.c129
-rw-r--r--src/journal/test-mmap-cache.c79
-rw-r--r--src/libsystemd-daemon/.gitignore1
l---------src/libsystemd-daemon/Makefile1
-rw-r--r--src/libsystemd-daemon/libsystemd-daemon.pc.in19
-rw-r--r--src/libsystemd-daemon/libsystemd-daemon.sym27
-rw-r--r--src/libsystemd-daemon/sd-daemon.c536
-rw-r--r--src/libsystemd-id128/.gitignore1
l---------src/libsystemd-id128/Makefile1
-rw-r--r--src/libsystemd-id128/libsystemd-id128.pc.in18
-rw-r--r--src/libsystemd-id128/libsystemd-id128.sym21
-rw-r--r--src/libsystemd-id128/sd-id128.c221
-rw-r--r--src/libudev/.gitignore1
l---------src/libudev/Makefile1
-rw-r--r--src/libudev/libudev-device-private.c192
-rw-r--r--src/libudev/libudev-device.c1758
-rw-r--r--src/libudev/libudev-enumerate.c956
-rw-r--r--src/libudev/libudev-hwdb-def.h74
-rw-r--r--src/libudev/libudev-hwdb.c392
-rw-r--r--src/libudev/libudev-list.c355
-rw-r--r--src/libudev/libudev-monitor.c782
-rw-r--r--src/libudev/libudev-private.h180
-rw-r--r--src/libudev/libudev-queue-private.c406
-rw-r--r--src/libudev/libudev-queue.c480
-rw-r--r--src/libudev/libudev-util.c725
-rw-r--r--src/libudev/libudev.c314
-rw-r--r--src/libudev/libudev.h204
-rw-r--r--src/libudev/libudev.pc.in18
-rw-r--r--src/libudev/libudev.sym110
-rw-r--r--src/locale/.gitignore1
l---------src/locale/Makefile1
-rwxr-xr-xsrc/locale/generate-kbd-model-map33
-rw-r--r--src/locale/kbd-model-map72
-rw-r--r--src/locale/localectl.c781
-rw-r--r--src/locale/localed.c1417
-rw-r--r--src/locale/org.freedesktop.locale1.conf27
-rw-r--r--src/locale/org.freedesktop.locale1.policy.in39
-rw-r--r--src/locale/org.freedesktop.locale1.service12
-rw-r--r--src/login/.gitignore5
-rw-r--r--src/login/70-power-switch.rules13
-rw-r--r--src/login/70-uaccess.rules75
-rw-r--r--src/login/71-seat.rules.in48
-rw-r--r--src/login/73-seat-late.rules.in17
l---------src/login/Makefile1
-rw-r--r--src/login/inhibit.c332
-rw-r--r--src/login/libsystemd-login.pc.in18
-rw-r--r--src/login/libsystemd-login.sym55
-rw-r--r--src/login/loginctl.c1611
-rw-r--r--src/login/logind-acl.c248
-rw-r--r--src/login/logind-acl.h57
-rw-r--r--src/login/logind-button.c322
-rw-r--r--src/login/logind-button.h67
-rw-r--r--src/login/logind-dbus.c2389
-rw-r--r--src/login/logind-device.c96
-rw-r--r--src/login/logind-device.h45
-rw-r--r--src/login/logind-gperf.gperf32
-rw-r--r--src/login/logind-inhibit.c468
-rw-r--r--src/login/logind-inhibit.h95
-rw-r--r--src/login/logind-seat-dbus.c444
-rw-r--r--src/login/logind-seat.c543
-rw-r--r--src/login/logind-seat.h83
-rw-r--r--src/login/logind-session-dbus.c590
-rw-r--r--src/login/logind-session.c1010
-rw-r--r--src/login/logind-session.h147
-rw-r--r--src/login/logind-user-dbus.c437
-rw-r--r--src/login/logind-user.c656
-rw-r--r--src/login/logind-user.h84
-rw-r--r--src/login/logind.c1680
-rw-r--r--src/login/logind.conf26
-rw-r--r--src/login/logind.h174
-rw-r--r--src/login/multi-seat-x.c108
-rw-r--r--src/login/org.freedesktop.login1.conf142
-rw-r--r--src/login/org.freedesktop.login1.policy.in259
-rw-r--r--src/login/org.freedesktop.login1.service12
-rw-r--r--src/login/pam-module.c716
-rw-r--r--src/login/sd-login.c794
-rw-r--r--src/login/sysfs-show.c190
-rw-r--r--src/login/test-inhibit.c139
-rw-r--r--src/login/test-login.c201
-rw-r--r--src/login/uaccess.c91
-rw-r--r--src/login/user-sessions.c101
l---------src/machine-id-setup/Makefile1
-rw-r--r--src/machine-id-setup/machine-id-setup-main.c102
l---------src/modules-load/Makefile1
-rw-r--r--src/modules-load/modules-load.c266
l---------src/notify/Makefile1
-rw-r--r--src/notify/notify.c228
l---------src/nspawn/Makefile1
-rw-r--r--src/nspawn/nspawn.c1444
l---------src/python-systemd/Makefile1
-rw-r--r--src/python-systemd/__init__.py18
-rw-r--r--src/python-systemd/_journal.c141
-rw-r--r--src/python-systemd/journal.py201
l---------src/quotacheck/Makefile1
-rw-r--r--src/quotacheck/quotacheck.c120
l---------src/random-seed/Makefile1
-rw-r--r--src/random-seed/random-seed.c149
l---------src/rc-local-generator/Makefile1
-rw-r--r--src/rc-local-generator/rc-local-generator.c115
l---------src/readahead/Makefile1
-rw-r--r--src/readahead/readahead-analyze.c150
-rw-r--r--src/readahead/readahead-collect.c623
-rw-r--r--src/readahead/readahead-common.c359
-rw-r--r--src/readahead/readahead-common.h61
-rw-r--r--src/readahead/readahead-replay.c311
-rw-r--r--src/readahead/readahead.c158
-rw-r--r--src/readahead/sd-readahead.c89
l---------src/remount-fs/Makefile1
-rw-r--r--src/remount-fs/remount-fs.c170
l---------src/reply-password/Makefile1
-rw-r--r--src/reply-password/reply-password.c109
l---------src/shared/Makefile1
-rw-r--r--src/shared/acl-util.c68
-rw-r--r--src/shared/acl-util.h24
-rw-r--r--src/shared/ask-password-api.c576
-rw-r--r--src/shared/ask-password-api.h30
-rw-r--r--src/shared/audit.c118
-rw-r--r--src/shared/audit.h32
-rw-r--r--src/shared/capability.c224
-rw-r--r--src/shared/capability.h33
-rw-r--r--src/shared/cgroup-label.c82
-rw-r--r--src/shared/cgroup-show.c351
-rw-r--r--src/shared/cgroup-show.h34
-rw-r--r--src/shared/cgroup-util.c1256
-rw-r--r--src/shared/cgroup-util.h74
-rw-r--r--src/shared/conf-files.c153
-rw-r--r--src/shared/conf-files.h31
-rw-r--r--src/shared/conf-parser.c1007
-rw-r--r--src/shared/conf-parser.h136
-rw-r--r--src/shared/dbus-common.c1326
-rw-r--r--src/shared/dbus-common.h222
-rw-r--r--src/shared/dbus-loop.c263
-rw-r--r--src/shared/dbus-loop.h27
-rw-r--r--src/shared/def.h35
-rw-r--r--src/shared/dev-setup.c78
-rw-r--r--src/shared/dev-setup.h24
-rw-r--r--src/shared/exit-status.c192
-rw-r--r--src/shared/exit-status.h88
-rw-r--r--src/shared/hashmap.c835
-rw-r--r--src/shared/hashmap.h98
-rw-r--r--src/shared/hwclock.c240
-rw-r--r--src/shared/hwclock.h31
-rw-r--r--src/shared/install.c2059
-rw-r--r--src/shared/install.h87
-rw-r--r--src/shared/ioprio.h57
-rw-r--r--src/shared/label.c382
-rw-r--r--src/shared/label.h47
l---------src/shared/linux/Makefile1
-rw-r--r--src/shared/linux/auto_dev-ioctl.h229
-rw-r--r--src/shared/linux/fanotify.h98
-rw-r--r--src/shared/linux/seccomp-bpf.h76
-rw-r--r--src/shared/linux/seccomp.h47
-rw-r--r--src/shared/list.h125
-rw-r--r--src/shared/log.c885
-rw-r--r--src/shared/log.h139
-rw-r--r--src/shared/logs-show.c904
-rw-r--r--src/shared/logs-show.h74
-rw-r--r--src/shared/macro.h242
-rw-r--r--src/shared/missing.h255
-rw-r--r--src/shared/mkdir.c147
-rw-r--r--src/shared/mkdir.h32
-rw-r--r--src/shared/pager.c143
-rw-r--r--src/shared/pager.h28
-rw-r--r--src/shared/path-lookup.c430
-rw-r--r--src/shared/path-lookup.h45
-rw-r--r--src/shared/path-util.c419
-rw-r--r--src/shared/path-util.h45
-rw-r--r--src/shared/polkit.c163
-rw-r--r--src/shared/polkit.h33
-rw-r--r--src/shared/ratelimit.c57
-rw-r--r--src/shared/ratelimit.h57
-rw-r--r--src/shared/replace-var.c110
-rw-r--r--src/shared/replace-var.h24
-rw-r--r--src/shared/selinux-util.c42
-rw-r--r--src/shared/selinux-util.h27
-rw-r--r--src/shared/set.c130
-rw-r--r--src/shared/set.h71
-rw-r--r--src/shared/socket-label.c143
-rw-r--r--src/shared/socket-util.c544
-rw-r--r--src/shared/socket-util.h99
-rw-r--r--src/shared/sparse-endian.h87
-rw-r--r--src/shared/spawn-ask-password-agent.c67
-rw-r--r--src/shared/spawn-ask-password-agent.h25
-rw-r--r--src/shared/spawn-polkit-agent.c86
-rw-r--r--src/shared/spawn-polkit-agent.h28
-rw-r--r--src/shared/specifier.c111
-rw-r--r--src/shared/specifier.h34
-rw-r--r--src/shared/strbuf.c176
-rw-r--r--src/shared/strbuf.h56
-rw-r--r--src/shared/strv.c750
-rw-r--r--src/shared/strv.h84
-rw-r--r--src/shared/time-dst.c341
-rw-r--r--src/shared/time-dst.h26
-rw-r--r--src/shared/unit-name.c519
-rw-r--r--src/shared/unit-name.h94
-rw-r--r--src/shared/utf8.c286
-rw-r--r--src/shared/utf8.h32
-rw-r--r--src/shared/util.c6215
-rw-r--r--src/shared/util.h615
-rw-r--r--src/shared/utmp-wtmp.c431
-rw-r--r--src/shared/utmp-wtmp.h35
-rw-r--r--src/shared/virt.c259
-rw-r--r--src/shared/virt.h35
-rw-r--r--src/shared/watchdog.c169
-rw-r--r--src/shared/watchdog.h28
l---------src/shutdownd/Makefile1
-rw-r--r--src/shutdownd/shutdownd.c478
l---------src/sleep/Makefile1
-rw-r--r--src/sleep/sleep.c127
l---------src/stdio-bridge/Makefile1
-rw-r--r--src/stdio-bridge/stdio-bridge.c367
l---------src/sysctl/Makefile1
-rw-r--r--src/sysctl/sysctl.c336
l---------src/system-update-generator/Makefile1
-rw-r--r--src/system-update-generator/system-update-generator.c84
l---------src/systemctl/Makefile1
-rw-r--r--src/systemctl/systemctl.c5354
l---------src/systemd/Makefile1
-rw-r--r--src/systemd/sd-daemon.h282
-rw-r--r--src/systemd/sd-id128.h109
-rw-r--r--src/systemd/sd-journal.h149
-rw-r--r--src/systemd/sd-login.h160
-rw-r--r--src/systemd/sd-messages.h69
-rw-r--r--src/systemd/sd-readahead.h73
-rw-r--r--src/systemd/sd-shutdown.h108
l---------src/test/Makefile1
-rw-r--r--src/test/test-cgroup.c105
-rw-r--r--src/test/test-daemon.c37
-rw-r--r--src/test/test-date.c69
-rw-r--r--src/test/test-engine.c99
-rw-r--r--src/test/test-env-replace.c143
-rw-r--r--src/test/test-hostname.c38
-rw-r--r--src/test/test-id128.c52
-rw-r--r--src/test/test-install.c265
-rw-r--r--src/test/test-job-type.c105
-rw-r--r--src/test/test-libudev.c520
-rw-r--r--src/test/test-log.c53
-rw-r--r--src/test/test-loopback.c37
-rw-r--r--src/test/test-ns.c61
-rw-r--r--src/test/test-replace-var.c46
-rw-r--r--src/test/test-sleep.c39
-rw-r--r--src/test/test-strv.c66
-rw-r--r--src/test/test-udev.c170
-rw-r--r--src/test/test-unit-file.c52
-rw-r--r--src/test/test-unit-name.c177
-rw-r--r--src/test/test-watchdog.c51
-rw-r--r--src/timedate/.gitignore1
l---------src/timedate/Makefile1
-rw-r--r--src/timedate/org.freedesktop.timedate1.conf27
-rw-r--r--src/timedate/org.freedesktop.timedate1.policy.in61
-rw-r--r--src/timedate/org.freedesktop.timedate1.service12
-rw-r--r--src/timedate/timedatectl.c719
-rw-r--r--src/timedate/timedated.c1042
l---------src/timestamp/Makefile1
-rw-r--r--src/timestamp/timestamp.c39
l---------src/tmpfiles/Makefile1
-rw-r--r--src/tmpfiles/tmpfiles.c1418
l---------src/tty-ask-password-agent/Makefile1
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c764
-rw-r--r--src/udev/.gitignore1
-rw-r--r--src/udev/.vimrc4
l---------src/udev/Makefile1
-rw-r--r--src/udev/accelerometer/accelerometer.c358
-rw-r--r--src/udev/ata_id/ata_id.c714
-rw-r--r--src/udev/cdrom_id/cdrom_id.c1099
-rw-r--r--src/udev/collect/collect.c492
-rw-r--r--src/udev/keymap/.gitignore5
-rw-r--r--src/udev/keymap/95-keyboard-force-release.rules57
-rw-r--r--src/udev/keymap/95-keymap.rules175
-rw-r--r--src/udev/keymap/README.keymap.txt97
-rwxr-xr-xsrc/udev/keymap/check-keymaps.sh38
-rwxr-xr-xsrc/udev/keymap/findkeyboards68
-rwxr-xr-xsrc/udev/keymap/keyboard-force-release.sh.in22
-rw-r--r--src/udev/keymap/keymap.c453
-rw-r--r--src/udev/mtd_probe/mtd_probe.c54
-rw-r--r--src/udev/mtd_probe/mtd_probe.h49
-rw-r--r--src/udev/mtd_probe/probe_smartmedia.c96
-rw-r--r--src/udev/scsi_id/.gitignore1
-rw-r--r--src/udev/scsi_id/README4
-rw-r--r--src/udev/scsi_id/scsi.h97
-rw-r--r--src/udev/scsi_id/scsi_id.c634
-rw-r--r--src/udev/scsi_id/scsi_id.h73
-rw-r--r--src/udev/scsi_id/scsi_serial.c968
-rw-r--r--src/udev/udev-builtin-blkid.c204
-rw-r--r--src/udev/udev-builtin-btrfs.c65
-rw-r--r--src/udev/udev-builtin-firmware.c172
-rw-r--r--src/udev/udev-builtin-hwdb.c159
-rw-r--r--src/udev/udev-builtin-input_id.c219
-rw-r--r--src/udev/udev-builtin-kmod.c134
-rw-r--r--src/udev/udev-builtin-net_id.c55
-rw-r--r--src/udev/udev-builtin-path_id.c549
-rw-r--r--src/udev/udev-builtin-uaccess.c99
-rw-r--r--src/udev/udev-builtin-usb_id.c477
-rw-r--r--src/udev/udev-builtin.c144
-rw-r--r--src/udev/udev-ctrl.c490
-rw-r--r--src/udev/udev-event.c905
-rw-r--r--src/udev/udev-node.c342
-rw-r--r--src/udev/udev-rules.c2573
-rw-r--r--src/udev/udev-watch.c161
-rw-r--r--src/udev/udev.conf3
-rw-r--r--src/udev/udev.h201
-rw-r--r--src/udev/udev.pc.in5
-rw-r--r--src/udev/udevadm-control.c175
-rw-r--r--src/udev/udevadm-hwdb.c601
-rw-r--r--src/udev/udevadm-info.c550
-rw-r--r--src/udev/udevadm-monitor.c297
-rw-r--r--src/udev/udevadm-settle.c232
-rw-r--r--src/udev/udevadm-test-builtin.c127
-rw-r--r--src/udev/udevadm-test.c172
-rw-r--r--src/udev/udevadm-trigger.c228
-rw-r--r--src/udev/udevadm.c152
-rw-r--r--src/udev/udevd.c1578
-rw-r--r--src/udev/v4l_id/v4l_id.c87
l---------src/update-utmp/Makefile1
-rw-r--r--src/update-utmp/update-utmp.c386
l---------src/vconsole/Makefile1
-rw-r--r--src/vconsole/vconsole-setup.c392
-rw-r--r--sysctl.d/.gitignore1
l---------sysctl.d/Makefile1
-rw-r--r--sysctl.d/coredump.conf.in10
-rw-r--r--test/.gitignore3
-rw-r--r--test/Makefile20
-rw-r--r--test/README.testsuite35
-rw-r--r--test/TEST-01-BASIC/Makefile10
-rwxr-xr-xtest/TEST-01-BASIC/test.sh252
l---------test/TEST-02-CRYPTSETUP/Makefile1
-rwxr-xr-xtest/TEST-02-CRYPTSETUP/test.sh264
-rw-r--r--test/a.service7
-rw-r--r--test/b.service6
-rw-r--r--test/c.service6
-rw-r--r--test/d.service8
-rw-r--r--test/e.service8
-rw-r--r--test/f.service5
-rw-r--r--test/g.service6
-rw-r--r--test/h.service6
-rwxr-xr-xtest/rule-syntax-check.py64
-rwxr-xr-xtest/rules-test.sh15
-rw-r--r--test/sys.tar.xzbin0 -> 165116 bytes
-rw-r--r--test/test-functions864
-rwxr-xr-xtest/udev-test.pl1530
l---------tmpfiles.d/Makefile1
-rw-r--r--tmpfiles.d/legacy.conf22
-rw-r--r--tmpfiles.d/systemd.conf28
-rw-r--r--tmpfiles.d/tmp.conf12
-rw-r--r--tmpfiles.d/x11.conf18
-rw-r--r--units/.gitignore49
l---------units/Makefile1
-rw-r--r--units/basic.target13
-rw-r--r--units/bluetooth.target11
-rw-r--r--units/console-getty.service.m4.in49
-rw-r--r--units/console-shell.service.m4.in52
-rw-r--r--units/cryptsetup.target10
-rw-r--r--units/debug-shell.service.in33
-rw-r--r--units/dev-hugepages.mount18
-rw-r--r--units/dev-mqueue.mount18
-rw-r--r--units/emergency.service.in31
-rw-r--r--units/emergency.target13
l---------units/fedora/Makefile1
-rw-r--r--units/fedora/halt-local.service20
-rw-r--r--units/fedora/rc-local.service19
-rw-r--r--units/final.target13
-rw-r--r--units/frugalware/display-manager.service16
-rw-r--r--units/getty.target10
-rw-r--r--units/getty@.service.m468
-rw-r--r--units/graphical.target18
-rw-r--r--units/halt.target17
-rw-r--r--units/hibernate.target13
-rw-r--r--units/hybrid-sleep.target13
-rw-r--r--units/kexec.target17
-rw-r--r--units/local-fs-pre.target10
-rw-r--r--units/local-fs.target12
-rw-r--r--units/mail-transfer-agent.target13
-rw-r--r--units/multi-user.target17
-rw-r--r--units/network.target10
-rw-r--r--units/nss-lookup.target14
-rw-r--r--units/nss-user-lookup.target14
-rw-r--r--units/poweroff.target17
-rw-r--r--units/printer.target11
-rw-r--r--units/proc-sys-fs-binfmt_misc.automount17
-rw-r--r--units/proc-sys-fs-binfmt_misc.mount16
-rw-r--r--units/quotaon.service.in19
-rw-r--r--units/reboot.target17
-rw-r--r--units/remote-fs-pre.target11
-rw-r--r--units/remote-fs.target13
-rw-r--r--units/rescue.service.m4.in40
-rw-r--r--units/rescue.target16
-rw-r--r--units/rpcbind.target13
-rw-r--r--units/serial-getty@.service.m455
-rw-r--r--units/shutdown.target12
-rw-r--r--units/sigpwr.target10
-rw-r--r--units/sleep.target13
-rw-r--r--units/smartcard.target11
-rw-r--r--units/sockets.target10
-rw-r--r--units/sound.target11
-rw-r--r--units/suse/halt-local.service20
-rw-r--r--units/suse/rc-local.service19
-rw-r--r--units/suspend.target13
-rw-r--r--units/swap.target10
-rw-r--r--units/sys-fs-fuse-connections.mount19
-rw-r--r--units/sys-kernel-config.mount19
-rw-r--r--units/sys-kernel-debug.mount18
-rw-r--r--units/sysinit.target14
-rw-r--r--units/syslog.socket43
-rw-r--r--units/syslog.target19
-rw-r--r--units/system-update.target16
-rw-r--r--units/systemd-ask-password-console.path19
-rw-r--r--units/systemd-ask-password-console.service.in18
-rw-r--r--units/systemd-ask-password-wall.path17
-rw-r--r--units/systemd-ask-password-wall.service.in15
-rw-r--r--units/systemd-binfmt.service.in26
-rw-r--r--units/systemd-fsck-root.service.in25
-rw-r--r--units/systemd-fsck@.service.in21
-rw-r--r--units/systemd-halt.service.in17
-rw-r--r--units/systemd-hibernate.service.in17
-rw-r--r--units/systemd-hostnamed.service.in16
-rw-r--r--units/systemd-hybrid-sleep.service.in17
-rw-r--r--units/systemd-initctl.service.in15
-rw-r--r--units/systemd-initctl.socket16
-rw-r--r--units/systemd-journal-flush.service.in18
-rw-r--r--units/systemd-journal-gatewayd.service.in16
-rw-r--r--units/systemd-journal-gatewayd.socket15
-rw-r--r--units/systemd-journald.service.in26
-rw-r--r--units/systemd-journald.socket26
-rw-r--r--units/systemd-kexec.service.in17
-rw-r--r--units/systemd-localed.service.in16
-rw-r--r--units/systemd-logind.service.in23
-rw-r--r--units/systemd-modules-load.service.in27
-rw-r--r--units/systemd-poweroff.service.in17
-rw-r--r--units/systemd-quotacheck.service.in20
-rw-r--r--units/systemd-random-seed-load.service.in18
-rw-r--r--units/systemd-random-seed-save.service.in18
-rw-r--r--units/systemd-readahead-collect.service.in28
-rw-r--r--units/systemd-readahead-done.service.in21
-rw-r--r--units/systemd-readahead-done.timer20
-rw-r--r--units/systemd-readahead-drop.service19
-rw-r--r--units/systemd-readahead-replay.service.in26
-rw-r--r--units/systemd-reboot.service.in17
-rw-r--r--units/systemd-remount-fs.service.in21
-rw-r--r--units/systemd-shutdownd.service.in15
-rw-r--r--units/systemd-shutdownd.socket18
-rw-r--r--units/systemd-suspend.service.in17
-rw-r--r--units/systemd-sysctl.service.in26
-rw-r--r--units/systemd-timedated.service.in16
-rw-r--r--units/systemd-tmpfiles-clean.service.in23
-rw-r--r--units/systemd-tmpfiles-clean.timer14
-rw-r--r--units/systemd-tmpfiles-setup.service.in23
-rw-r--r--units/systemd-udev-settle.service.in30
-rw-r--r--units/systemd-udev-trigger.service.in19
-rw-r--r--units/systemd-udevd-control.socket18
-rw-r--r--units/systemd-udevd-kernel.socket18
-rw-r--r--units/systemd-udevd.service.in23
-rw-r--r--units/systemd-update-utmp-runlevel.service.in19
-rw-r--r--units/systemd-update-utmp-shutdown.service.in19
-rw-r--r--units/systemd-user-sessions.service.in17
-rw-r--r--units/systemd-vconsole-setup.service.in20
-rw-r--r--units/time-sync.target13
-rw-r--r--units/tmp.mount19
-rw-r--r--units/umount.target12
-rw-r--r--units/user/.gitignore1
l---------units/user/Makefile1
-rw-r--r--units/user/default.target10
-rw-r--r--units/user/exit.target17
-rw-r--r--units/user/systemd-exit.service.in17
-rw-r--r--units/user@.service.in19
967 files changed, 376354 insertions, 0 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000000..9d9f8cd178
--- /dev/null
+++ b/.dir-locals.el
@@ -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
index 0000000000..18e4e23c50
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,144 @@
+/test-replace-var
+/test-journal-enum
+/test-sleep
+/localectl
+/hostnamectl
+/timedatectl
+/test-date
+/install-tree
+/systemd-journal-gatewayd
+/test-mmap-cache
+/test-unit-file
+/test-log
+/test-journal-verify
+/test-journal-match
+/test-journal-stream
+/test-unit-name
+/systemd-system-update-generator
+/systemd-fstab-generator
+/systemd-delta
+/systemd-sleep
+/systemd-inhibit
+/systemd-remount-fs
+/build-aux
+/test-watchdog
+/test-journal-send
+/test-journal-syslog
+/systemd-multi-seat-x
+/systemd-cgtop
+/systemd-coredump
+/systemd-cat
+/systemd-rc-local-generator
+/journalctl
+/systemd-journald
+/test-id128
+/test-journal
+/test-install
+/test-inhibit
+/org.freedesktop.hostname1.xml
+/org.freedesktop.locale1.xml
+/test-login
+/loginctl
+/systemd-localed
+/systemd-timedated
+/org.freedesktop.timedate1.xml
+/systemd-logind
+/systemd-uaccess
+/systemd-hostnamed
+/systemd-binfmt
+/systemd-getty-generator
+/systemd-nspawn
+/systemd-stdio-bridge
+/systemd-machine-id-setup
+/systemd-detect-virt
+/systemd-sysctl
+/test-strv
+/systemd-ac-power
+/systemd-timestamp
+/systemd-coredumpctl
+/systemd-cryptsetup
+/systemd-cryptsetup-generator
+/systemd-tty-ask-password-agent
+/systemd-fsck
+/systemd-quotacheck
+/systemd-user-sessions
+/systemd-shutdown
+/systemd-tmpfiles
+/systemd-readahead
+/systemd-reply-password
+/systemd-gnome-ask-password-agent
+/systemd-ask-password
+/systemd-kmsg-syslogd
+/systemd-remount-api-vfs
+/test-hostname
+/systemd-modules-load
+/systemd-vconsole-setup
+/systemd-shutdownd
+/systemd-random-seed
+/systemd-update-utmp
+/test-env-replace
+/systemd-cgls
+/test-cgroup
+.libs/
+/systemd-notify
+/test-daemon
+/org.freedesktop.systemd1.*.xml
+/test-ns
+/test-loopback
+/systemd-cgroups-agent
+/systemd-initctl
+/systemd
+/test-engine
+/test-job-type
+/systemctl
+/systemadm
+.dirstamp
+*.1
+*.3
+*.5
+*.7
+*.8
+*.html
+*~
+*.o
+*.lo
+*.a
+*.la
+.deps/
+Makefile.in
+aclocal.m4
+*.cache
+compile
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+depcomp
+install-sh
+missing
+stamp-*
+*.stamp
+/Makefile
+/ltmain.sh
+/*.tar.xz
+/*.tar.gz
+/*.tar.bz2
+/libtool
+/accelerometer
+/ata_id
+/cdrom_id
+/collect
+/gtk-doc.make
+/keymap
+/mtd_probe
+/scsi_id
+/udevadm
+/systemd-udevd
+/v4l_id
+/test-libudev
+/test-udev
+/TAGS
+/tags
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..da8ca84438
--- /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
index 0000000000..366fbdca4b
--- /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
index 0000000000..04b4ed20e9
--- /dev/null
+++ b/CODING_STYLE
@@ -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
index 0000000000..2b08bf8116
--- /dev/null
+++ b/DISTRO_PORTING
@@ -0,0 +1,58 @@
+Porting systemd To New Distributions
+
+HOWTO:
+ You need to make the follow changes to adapt systemd to your
+ distribution:
+
+ 0) Make your distribution recognized via the autoconf checks
+ in configure.ac. Grep for the word "fedora" (case
+ insensitively) and you should be able to find the places where
+ you need to add/change things.
+
+ 1) Patch src/hostname-setup.c so that systemd knows where to
+ read your host name from. You might also want to update
+ status_welcome() in util.c.
+
+ 2) Check the unit files in units/ if they match your
+ distribution. Most likely you will have to make additions to
+ units/*.m4 and create a copy of units/fedora/ with changes for
+ your distribution.
+
+ 3) Adjust Makefile.am to register the unit files you added in
+ step 2. Also you might need to update the m4 invocation in
+ Makefile.am. Grep for the word "fedora" (case insensitively)
+ and you should be able to find the places where you need to
+ add/change things.
+
+ 4) 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 interested in merging your changes upstream, if they
+ are for a big, and well-known distribution. Unfortunately we
+ don't have the time and resources to maintain
+ distribution-specific patches for all distributions on the
+ planet, hence please do not send us patches that add systemd
+ support for non-mainstream or niche distributions.
+
+ Thank you for understanding.
+
+BE CONSIDERATE:
+ We'd like to keep differences between the distributions
+ minimal. This both simplifies our maintenance work, as well
+ as it helps administrators to move from one distribution to
+ another.
+
+ Hence we'd like to ask you to keep your changes minimal, and
+ not rename any units without a very good reason (if you need a
+ particular name for compatibility reasons, consider using
+ alias names via symlinks). Before you make changes that change
+ semantics from upstream, please talk to us!
+
+ In SysV almost every distribution uses a different
+ nomenclature and different locations for the boot-up
+ scripts. We'd like to avoid chaos like that with systemd right
+ from the beginning. So please, be considerate!
diff --git a/LICENSE.GPL2 b/LICENSE.GPL2
new file mode 100644
index 0000000000..d511905c16
--- /dev/null
+++ b/LICENSE.GPL2
@@ -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
index 0000000000..89d4489cec
--- /dev/null
+++ b/LICENSE.LGPL2.1
@@ -0,0 +1,508 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+^L
+ 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.
+^L
+ 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.
+
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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
+^L
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
index 0000000000..fd44f736ee
--- /dev/null
+++ b/LICENSE.MIT
@@ -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
index 0000000000..e3b629f89e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,4045 @@
+# -*- 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
+
+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=9
+LIBSYSTEMD_LOGIN_AGE=3
+
+LIBSYSTEMD_DAEMON_CURRENT=0
+LIBSYSTEMD_DAEMON_REVISION=5
+LIBSYSTEMD_DAEMON_AGE=0
+
+LIBSYSTEMD_ID128_CURRENT=0
+LIBSYSTEMD_ID128_REVISION=15
+LIBSYSTEMD_ID128_AGE=0
+
+LIBSYSTEMD_JOURNAL_CURRENT=6
+LIBSYSTEMD_JOURNAL_REVISION=0
+LIBSYSTEMD_JOURNAL_AGE=6
+
+# 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)
+varlogdir=$(localstatedir)/log
+
+# 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
+
+# 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 =
+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)\" \
+ -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)\" \
+ -DRUNTIME_DIR=\"/run\" \
+ -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)
+
+# ------------------------------------------------------------------------------
+if TARGET_GENTOO
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/usr/bin/setfont\"
+else
+if TARGET_ARCH
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/usr/bin/setfont\"
+else
+if TARGET_FRUGALWARE
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/usr/bin/setfont\"
+else
+if TARGET_MANDRIVA
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/bin/setfont\"
+else
+if TARGET_ANGSTROM
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/usr/bin/setfont\"
+else
+if TARGET_MAGEIA
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/bin/setfont\"
+else
+AM_CPPFLAGS += \
+ -DKBD_LOADKEYS=\"/bin/loadkeys\" \
+ -DKBD_SETFONT=\"/bin/setfont\"
+endif
+endif
+endif
+endif
+endif
+endif
+
+# ------------------------------------------------------------------------------
+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
+
+dist_bin_SCRIPTS = \
+ src/analyze/systemd-analyze
+
+rootlibexec_PROGRAMS = \
+ systemd \
+ systemd-cgroups-agent \
+ systemd-initctl \
+ systemd-update-utmp \
+ systemd-shutdownd \
+ systemd-shutdown \
+ systemd-modules-load \
+ systemd-remount-fs \
+ systemd-reply-password \
+ systemd-fsck \
+ systemd-timestamp \
+ systemd-ac-power \
+ systemd-sysctl \
+ systemd-sleep
+
+systemgenerator_PROGRAMS = \
+ systemd-getty-generator \
+ systemd-fstab-generator \
+ systemd-system-update-generator
+
+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-modules-load.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
+
+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-modules-load.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 TARGET_FEDORA
+dist_systemunit_DATA += \
+ units/fedora/rc-local.service \
+ units/fedora/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
+endif
+
+if TARGET_MANDRIVA
+dist_systemunit_DATA += \
+ units/fedora/rc-local.service \
+ units/fedora/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
+endif
+
+if TARGET_FRUGALWARE
+dist_systemunit_DATA += \
+ units/frugalware/display-manager.service
+endif
+
+if TARGET_SUSE
+dist_systemunit_DATA += \
+ units/suse/rc-local.service \
+ units/suse/halt-local.service
+systemgenerator_PROGRAMS += \
+ systemd-rc-local-generator
+endif
+
+if TARGET_MAGEIA
+dist_systemunit_DATA += \
+ units/fedora/rc-local.service \
+ units/fedora/halt-local.service
+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/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/modules-load.d.5 \
+ man/systemd-modules-load.service.8 \
+ 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
+
+MANPAGES_ALIAS = \
+ man/reboot.8 \
+ man/poweroff.8 \
+ man/init.1 \
+ man/systemd-modules-load.8 \
+ 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/reboot.8: man/halt.8
+man/poweroff.8: man/halt.8
+man/init.1: man/systemd.1
+man/systemd-modules-load.8: man/systemd-modules-load.service.8
+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
+
+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.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/hashmap.c \
+ src/shared/hashmap.h \
+ src/shared/set.c \
+ src/shared/set.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
+
+#-------------------------------------------------------------------------------
+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/kmod-setup.c \
+ src/core/kmod-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/fdset.c \
+ src/core/fdset.h \
+ 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
+
+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 \
+ 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
+
+TESTS += \
+ test-job-type \
+ test-env-replace \
+ test-strv \
+ test-unit-name \
+ test-unit-file \
+ test-date \
+ test-sleep \
+ test-replace-var
+
+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_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_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
+
+# ------------------------------------------------------------------------------
+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
+
+# ------------------------------------------------------------------------------
+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)
+
+# ------------------------------------------------------------------------------
+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:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-daemon.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-daemon.so && \
+ mv $(DESTDIR)$(libdir)/libsystemd-daemon.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+INSTALL_EXEC_HOOKS += \
+ libsystemd-daemon-install-hook
+
+libsystemd-daemon-uninstall-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so*
+
+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-move-hook:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libudev.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libudev.so && \
+ mv $(DESTDIR)$(libdir)/libudev.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+libudev-uninstall-move-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libudev.so*
+
+INSTALL_EXEC_HOOKS += libudev-install-move-hook
+UNINSTALL_EXEC_HOOKS += libudev-uninstall-move-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-drivers.rules \
+ rules/95-udev-late.rules
+
+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-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-blkid.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-kmod.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_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
+
+# ------------------------------------------------------------------------------
+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-move-hook:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libgudev-1.0.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libgudev-1.0.so && \
+ mv $(DESTDIR)$(libdir)/libgudev-1.0.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+libgudev-uninstall-move-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libgudev-1.0.so*
+
+INSTALL_EXEC_HOOKS += libgudev-install-move-hook
+UNINSTALL_EXEC_HOOKS += libgudev-uninstall-move-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-90x3a \
+ 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-90x3a \
+ 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:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-id128.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-id128.so && \
+ mv $(DESTDIR)$(libdir)/libsystemd-id128.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+INSTALL_EXEC_HOOKS += \
+ libsystemd-id128-install-hook
+
+libsystemd-id128-uninstall-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so*
+
+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
+
+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/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-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
+
+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:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-journal.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-journal.so && \
+ mv $(DESTDIR)$(libdir)/libsystemd-journal.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+INSTALL_EXEC_HOOKS += \
+ libsystemd-journal-install-hook
+
+libsystemd-journal-uninstall-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so*
+
+UNINSTALL_EXEC_HOOKS += \
+ libsystemd-journal-uninstall-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
+
+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
+
+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 > 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-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:
+ if test "$(libdir)" != "$(rootlibdir)"; then \
+ $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-login.so) && \
+ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
+ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-login.so && \
+ mv $(DESTDIR)$(libdir)/libsystemd-login.so.* $(DESTDIR)$(rootlibdir); \
+ fi
+
+INSTALL_EXEC_HOOKS += \
+ libsystemd-login-install-hook
+
+libsystemd-login-uninstall-hook:
+ rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so*
+
+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)$(localstatedir)/lib/systemd
+ ( 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,@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' \
+ < $< > $@
+
+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/%.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
+
+
+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-modules-load.service \
+ 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-modules-load.service systemd-modules-load.service && \
+ $(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 TARGET_FEDORA
+ ( cd $(DESTDIR)$(systemunitdir) && \
+ rm -f display-manager.service single.service && \
+ $(LN_S) rescue.service single.service )
+endif
+
+if TARGET_MANDRIVA
+ ( cd $(DESTDIR)$(systemunitdir) && \
+ rm -f display-manager.service dm.service single.service && \
+ $(LN_S) rescue.service single.service )
+endif
+
+if TARGET_DEBIAN_OR_UBUNTU
+ ( cd $(DESTDIR)$(systemunitdir) && \
+ rm -f runlevel5.target && \
+ $(LN_S) multi-user.target runlevel5.target )
+endif
+
+if TARGET_SUSE
+ ( cd $(DESTDIR)$(systemunitdir) && \
+ rm -f local.service && \
+ $(LN_S) rc-local.service local.service )
+endif
+
+if TARGET_MAGEIA
+ ( cd $(DESTDIR)$(systemunitdir) && \
+ rm -f display-manager.service )
+endif
+
+install-exec-hook: $(INSTALL_EXEC_HOOKS)
+
+uninstall-hook: $(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
+
+DISTCHECK_CONFIGURE_FLAGS = \
+ --with-sysvinit-path=$$dc_install_base/$(sysvinitdir) \
+ --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 ENABLE_GTK_DOC
+DISTCHECK_CONFIGURE_FLAGS += \
+ --enable-gtk-doc
+endif
+
+hwdb-update:
+ ( cd hwdb && \
+ wget -N http://www.linux-usb.org/usb.ids && \
+ wget -N http://pci-ids.ucw.cz/v2.2/pci.ids && \
+ wget -N http://standards.ieee.org/develop/regauth/oui/oui.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
index 0000000000..7628ba806e
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,1149 @@
+systemd System and Service Manager
+
+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/TODO b/TODO
new file mode 100644
index 0000000000..2488ee3b76
--- /dev/null
+++ b/TODO
@@ -0,0 +1,609 @@
+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
+
+* add rpm macros for %rulesdir, %hwdbdir, update rules/hwdb call
+
+Features:
+
+* 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
+
+* introduce ntp.service (or suchlike) as symlink that is used to arbitrate between various
+ NTP implementations
+
+* sd-journal: don't return fields > a threshold by default
+* 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
+
+* link up selected blog stories from man pages?
+
+* 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
+
+* don't show cgroup in "systemctl status" if empty/non-existent, especially for foreign .mount units
+
+* 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
+
+* nspawn: consider changing users for -u with su, so that NSS resolving works correctly
+
+* nspawn: implement personality changes a la linux32(8)
+
+* nspawn: reset all aux groups
+
+* 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
+
+* need to update LGPL2.1 text to newest version (with updated FSF address)
+
+* 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
+
+* make nspawn work without terminal
+
+* 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
+
+* 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
+
+* ability to pass fds into systemd
+
+* 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
+
+* 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 contrller 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
+
+* logind: auto-suspend, auto-shutdown:
+ IdleAction=(none|suspend|opportunistic|hibernate|poweroff)
+ IdleActionDelay=...
+ SessionIdleMode=(explicit|ignore|login)
+ ForceShutdown=(yes|no)
+
+* 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
+
+* 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
+
+* journal: message catalog
+
+* 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
+
+* readahead: check whether a btrfs volume includes ssd by checking mount flag "ssd"
+
+* 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
+
+* 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'
+
+* calendar time support in timer:
+ https://docs.google.com/document/pub?id=1bAMyFAjWLpzR3GTDYdgj5FWRMxoZiWw5zmUHEtvdHKA
+
+* 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
+
+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
index 0000000000..33d8fcda23
--- /dev/null
+++ b/autogen.sh
@@ -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/configure.ac b/configure.ac
new file mode 100644
index 0000000000..71ea6ad25b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,881 @@
+#
+# 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],
+ [195],
+ [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])])
+
+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 "$have_python" = "yes"])
+
+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])
+PKG_CHECK_MODULES(KMOD, [libkmod >= 5])
+PKG_CHECK_MODULES(BLKID,[blkid >= 2.20])
+
+# ------------------------------------------------------------------------------
+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_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(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"])
+
+# ------------------------------------------------------------------------------
+
+AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO],[Specify the distribution to target: One of fedora, suse, debian, ubuntu, arch, gentoo, slackware, altlinux, mandriva, mageia, angstrom or other]))
+if test "z$with_distro" = "z"; then
+ if test "$cross_compiling" = yes; then
+ AC_MSG_WARN([Target distribution cannot be reliably detected when cross-compiling. You should specify it with --with-distro (see $0 --help for recognized distros)])
+ else
+ with_distro=$($GREP '^ID=' /etc/os-release 2>/dev/null | $SED 's/ID=//');
+ fi
+ if test "z$with_distro" = "z"; then
+ with_distro=other
+ fi
+fi
+with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' `
+AC_DEFINE_UNQUOTED(DISTRIBUTION, ["${with_distro}"], [Target Distribution])
+
+# Location of the init scripts as mandated by LSB
+SYSTEM_SYSVINIT_PATH=/etc/init.d
+SYSTEM_SYSVRCND_PATH=/etc/rc.d
+
+M4_DEFINES=
+
+case $with_distro in
+ fedora)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+ AC_DEFINE(TARGET_FEDORA, [], [Target is Fedora/RHEL])
+ M4_DEFINES=-DTARGET_FEDORA=1
+ ;;
+ opensuse|suse)
+ SYSTEM_SYSVRCND_PATH=/etc/init.d
+ AC_DEFINE(TARGET_SUSE, [], [Target is openSUSE/SLE])
+ M4_DEFINES=-DTARGET_SUSE=1
+ ;;
+ debian)
+ SYSTEM_SYSVRCND_PATH=/etc
+ AC_DEFINE(TARGET_DEBIAN, [], [Target is Debian])
+ M4_DEFINES=-DTARGET_DEBIAN=1
+ ;;
+ ubuntu)
+ SYSTEM_SYSVRCND_PATH=/etc
+ AC_DEFINE(TARGET_UBUNTU, [], [Target is Ubuntu])
+ M4_DEFINES=-DTARGET_UBUNTU=1
+ ;;
+ arch)
+ SYSTEM_SYSVINIT_PATH=
+ SYSTEM_SYSVRCND_PATH=
+ AC_DEFINE(TARGET_ARCH, [], [Target is ArchLinux])
+ M4_DEFINES=-DTARGET_ARCH=1
+ ;;
+ gentoo)
+ SYSTEM_SYSVINIT_PATH=
+ SYSTEM_SYSVRCND_PATH=
+ AC_DEFINE(TARGET_GENTOO, [], [Target is Gentoo])
+ M4_DEFINES=-DTARGET_GENTOO=1
+ ;;
+ slackware)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+ AC_DEFINE(TARGET_SLACKWARE, [], [Target is Slackware])
+ M4_DEFINES=-DTARGET_SLACKWARE=1
+ ;;
+ frugalware)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d
+ AC_DEFINE(TARGET_FRUGALWARE, [], [Target is Frugalware])
+ M4_DEFINES=-DTARGET_FRUGALWARE=1
+ ;;
+ altlinux)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+ AC_DEFINE(TARGET_ALTLINUX, [], [Target is ALTLinux])
+ M4_DEFINES=-DTARGET_ALTLINUX=1
+ ;;
+ mandriva)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+ AC_DEFINE(TARGET_MANDRIVA, [], [Target is Mandriva])
+ M4_DEFINES=-DTARGET_MANDRIVA=1
+ ;;
+ angstrom)
+ SYSTEM_SYSVRCND_PATH=/etc
+ AC_DEFINE(TARGET_ANGSTROM, [], [Target is Ångström])
+ M4_DEFINES=-DTARGET_ANGSTROM=1
+ ;;
+ mageia)
+ SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d
+ AC_DEFINE(TARGET_MAGEIA, [], [Target is Mageia])
+ M4_DEFINES=-DTARGET_MAGEIA=1
+ ;;
+ other)
+ ;;
+ *)
+ AC_MSG_ERROR([Your distribution (${with_distro}) is not yet supported, SysV init scripts could not be found! (patches welcome); you can specify --with-distro=other to skip this check])
+ ;;
+esac
+
+AC_ARG_WITH([sysvinit-path],
+ [AS_HELP_STRING([--with-sysvinit-path=PATH],
+ [Specify the path to where the SysV init scripts are located @<:@default=based on distro@:>@])],
+ [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 @<:@default=based on distro@:>@])],
+ [SYSTEM_SYSVRCND_PATH="$withval"],
+ [])
+
+AC_SUBST(SYSTEM_SYSVINIT_PATH)
+AC_SUBST(SYSTEM_SYSVRCND_PATH)
+AC_SUBST(M4_DEFINES)
+
+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_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])],
+ [])
+
+AM_CONDITIONAL(TARGET_FEDORA, test x"$with_distro" = xfedora)
+AM_CONDITIONAL(TARGET_SUSE, test x"$with_distro" = xsuse)
+AM_CONDITIONAL(TARGET_DEBIAN, test x"$with_distro" = xdebian)
+AM_CONDITIONAL(TARGET_UBUNTU, test x"$with_distro" = xubuntu)
+AM_CONDITIONAL(TARGET_DEBIAN_OR_UBUNTU, test x"$with_distro" = xdebian -o x"$with_distro" = xubuntu)
+AM_CONDITIONAL(TARGET_ARCH, test x"$with_distro" = xarch)
+AM_CONDITIONAL(TARGET_GENTOO, test x"$with_distro" = xgentoo)
+AM_CONDITIONAL(TARGET_SLACKWARE, test x"$with_distro" = xslackware)
+AM_CONDITIONAL(TARGET_FRUGALWARE, test x"$with_distro" = xfrugalware)
+AM_CONDITIONAL(TARGET_ALTLINUX, test x"$with_distro" = xaltlinux)
+AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva)
+AM_CONDITIONAL(TARGET_ANGSTROM, test x"$with_distro" = xangstrom)
+AM_CONDITIONAL(TARGET_MAGEIA, test x"$with_distro" = xmageia)
+
+AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes")
+
+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
+
+ Distribution: ${with_distro}
+ SysV compatibility: ${SYSTEM_SYSV_COMPAT}
+ SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
+ SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
+ 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}
+ 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}
+ firmware path: ${FIRMWARE_PATH}
+ gudev: ${enable_gudev}
+ gintrospection: ${enable_introspection}
+ keymap: ${enable_keymap}
+ Python: ${have_python}
+ Python Headers: ${have_python_devel}
+
+ prefix: ${prefix}
+ rootprefix: ${with_rootprefix}
+ sysconf dir: ${sysconfdir}
+ datarootdir: ${datarootdir}
+ includedir: ${includedir}
+ include_prefix: ${INCLUDE_PREFIX}
+ lib dir: ${libdir}
+ rootlib dir: ${with_rootlibdir}
+ 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}
+ Split /usr: ${enable_split_usr}
+ man pages: ${have_manpages}
+ gtk-doc: ${enable_gtk_doc}
+
+ 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
index 0000000000..e9fed442c2
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1 @@
+/gtk-doc.make
diff --git a/docs/Makefile b/docs/Makefile
new file mode 120000
index 0000000000..bd1047548b
--- /dev/null
+++ b/docs/Makefile
@@ -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
index 0000000000..e6f2371ab1
--- /dev/null
+++ b/docs/gudev/.gitignore
@@ -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
index 0000000000..57334b6ddc
--- /dev/null
+++ b/docs/gudev/Makefile.am
@@ -0,0 +1,113 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10
+
+# 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
index 0000000000..3e7e50acd4
--- /dev/null
+++ b/docs/gudev/gudev-docs.xml
@@ -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
index 0000000000..b25c13bcb1
--- /dev/null
+++ b/docs/gudev/gudev-sections.txt
@@ -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
index 0000000000..a89857a04d
--- /dev/null
+++ b/docs/gudev/gudev.types
@@ -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
index 0000000000..d78bda9342
--- /dev/null
+++ b/docs/gudev/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/docs/libudev/.gitignore b/docs/libudev/.gitignore
new file mode 100644
index 0000000000..f8dd67c50a
--- /dev/null
+++ b/docs/libudev/.gitignore
@@ -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
index 0000000000..c6d7b8ca25
--- /dev/null
+++ b/docs/libudev/Makefile.am
@@ -0,0 +1,107 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10
+
+# 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
index 0000000000..454cd31646
--- /dev/null
+++ b/docs/libudev/libudev-docs.xml
@@ -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
index 0000000000..067a3f5b95
--- /dev/null
+++ b/docs/libudev/libudev-sections.txt
@@ -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
index 0000000000..e69de29bb2
--- /dev/null
+++ b/docs/libudev/libudev.types
diff --git a/docs/libudev/version.xml.in b/docs/libudev/version.xml.in
new file mode 100644
index 0000000000..d78bda9342
--- /dev/null
+++ b/docs/libudev/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/docs/sysvinit/.gitignore b/docs/sysvinit/.gitignore
new file mode 100644
index 0000000000..c3fea7424f
--- /dev/null
+++ b/docs/sysvinit/.gitignore
@@ -0,0 +1 @@
+/README
diff --git a/docs/sysvinit/Makefile b/docs/sysvinit/Makefile
new file mode 120000
index 0000000000..50be21181f
--- /dev/null
+++ b/docs/sysvinit/Makefile
@@ -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
index 0000000000..996402d06b
--- /dev/null
+++ b/docs/sysvinit/README.in
@@ -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
index 0000000000..c3fea7424f
--- /dev/null
+++ b/docs/var-log/.gitignore
@@ -0,0 +1 @@
+/README
diff --git a/docs/var-log/Makefile b/docs/var-log/Makefile
new file mode 120000
index 0000000000..50be21181f
--- /dev/null
+++ b/docs/var-log/Makefile
@@ -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
index 0000000000..2e64fb196a
--- /dev/null
+++ b/docs/var-log/README.in
@@ -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
index 0000000000..316529a943
--- /dev/null
+++ b/hwdb/.gitignore
@@ -0,0 +1,3 @@
+/pci.ids
+/usb.ids
+/oui.txt
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
new file mode 100644
index 0000000000..451bd3c914
--- /dev/null
+++ b/hwdb/20-OUI.hwdb
@@ -0,0 +1,51108 @@
+# This file is part of systemd.
+#
+# Data imported and updated from: http://standards.ieee.org/develop/regauth/oui/oui.txt
+
+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:00006C
+ ID_OUI_FROM_DATABASE=
+
+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:000101
+ ID_OUI_FROM_DATABASE=
+
+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=Prueftechnik 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:00054F
+ ID_OUI_FROM_DATABASE=
+
+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:000578
+ ID_OUI_FROM_DATABASE=
+
+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. Buero
+
+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
+
+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
+
+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=Suetron 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 Automaoa 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
+
+OUI:000830
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:000831
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Wuensche
+
+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
+
+OUI:0008A4
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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
+
+OUI:0008E3
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 &amp; 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
+
+OUI:000912
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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&amp;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
+
+OUI:000944
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00097C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0009B7
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0009E9
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000A42
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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-Buero 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
+
+OUI:000A8B
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000AB8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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.STI.
+
+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
+
+OUI:000AF4
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000B18
+ ID_OUI_FROM_DATABASE=
+
+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=Knuerr 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=OpNext Inc.
+
+OUI:000B41
+ ID_OUI_FROM_DATABASE=Ing. Buero 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
+
+OUI:000B46
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+OUI:000B60
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:000B61
+ ID_OUI_FROM_DATABASE=Friedrich Lütze GmbH &Co.
+
+OUI:000B62
+ ID_OUI_FROM_DATABASE=Ingenieurbuero fuer 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
+
+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 m
+
+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
+
+OUI:000BBF
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000BF4
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000BFD
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000C31
+ ID_OUI_FROM_DATABASE=Cisco
+
+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:000C53
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000C86
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000CCF
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000D29
+ ID_OUI_FROM_DATABASE=Cisco
+
+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:000D58
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000D66
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000DA7
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000DBD
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000DC2
+ ID_OUI_FROM_DATABASE=
+
+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=PROFÃÂÂÂLO TELRA ELEKTRONÃÂÂÂK SANAYàVE TÃÂÂÂCARET 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
+
+OUI:000DED
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000DF2
+ ID_OUI_FROM_DATABASE=
+
+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:000E17
+ ID_OUI_FROM_DATABASE=
+
+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:000E22
+ ID_OUI_FROM_DATABASE=
+
+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:000E2A
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000E39
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000E84
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000ED7
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:000EEF
+ ID_OUI_FROM_DATABASE=
+
+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:000F09
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:000F24
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000F35
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000F90
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:000FF8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001121
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00115D
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+OUI:001193
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0011BC
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001201
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+OUI:001244
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+OUI:001280
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+OUI:0012DA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00131A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001360
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001380
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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=Xsigo Systems, Inc.
+
+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
+
+OUI:0013C4
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Prozessautomation 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
+
+OUI:00141C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00146A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0014A9
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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- u. 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
+
+OUI:0014F2
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00152C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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=Bus-Tech, Inc.
+
+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
+
+OUI:001563
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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=scil animal care company 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
+
+OUI:0015C7
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0015FA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001647
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00169D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:0016B4
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:0016C8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00170F
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:001735
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:00175A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001795
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0017E0
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001819
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:001825
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:001874
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0018BA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Ltda.
+
+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
+
+OUI:001907
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001930
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001956
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0019AA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0019E8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001A30
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001A6D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001AA2
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001AE3
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001B0D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001B2B
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001B54
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001B90
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001BD5
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001C0F
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001C58
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Technology (HK) Ltd.
+
+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
+
+OUI:001CB1
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001CF7
+ ID_OUI_FROM_DATABASE=AudioScience
+
+OUI:001CF8
+ ID_OUI_FROM_DATABASE=Parade Technologies, Ltd.
+
+OUI:001CF9
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001D46
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Informatica 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
+
+OUI:001D71
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001DA2
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001DE6
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001E14
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001E4A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001E7A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001EBE
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001EF7
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001F27
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001F6D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001F9E
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:001FCA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:002067
+ ID_OUI_FROM_DATABASE=
+
+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=DIGIMEDIA VISION LTD.
+
+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
+
+OUI:00211C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002156
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0021A1
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0021D8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00220D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:00221C
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:002256
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Messtechnik 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
+
+OUI:002291
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0022BE
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Eletronica 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:0022F1
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:002305
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002334
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:00234A
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:00235E
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:00238C
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:0023AC
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0023EB
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:0023F7
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:002414
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:002419
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:002451
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002498
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0024C4
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:0024F8
+ ID_OUI_FROM_DATABASE=Technical Solutions Company Ltd.
+
+OUI:0024F9
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:0024FA
+ ID_OUI_FROM_DATABASE=Hilger u. Kern GMBH
+
+OUI:0024FB
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:002546
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002584
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:00259D
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:0025B5
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:0025DF
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:00260B
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002652
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:002699
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:00269F
+ ID_OUI_FROM_DATABASE=
+
+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
+
+OUI:0026CB
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+OUI:00270D
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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
+
+OUI:003A99
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:003A9A
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:003A9B
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:003A9C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:005047
+ ID_OUI_FROM_DATABASE=
+
+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:005079
+ ID_OUI_FROM_DATABASE=
+
+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=IWAKI ELECTRONICS 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:0050C2
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY
+
+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
+
+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:00A054
+ ID_OUI_FROM_DATABASE=
+
+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:00A085
+ ID_OUI_FROM_DATABASE=
+
+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=RELDATA Inc
+
+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: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
+
+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: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:04180F
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0418B6
+ ID_OUI_FROM_DATABASE=
+
+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: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: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: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
+
+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: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
+
+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: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
+
+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:081FF3
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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: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: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
+
+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: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: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:0C8112
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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
+
+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:100000
+ ID_OUI_FROM_DATABASE=
+
+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: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:1056CA
+ ID_OUI_FROM_DATABASE=Peplink International Ltd.
+
+OUI:105CBF
+ ID_OUI_FROM_DATABASE=DuroByte 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
+
+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:10BAA5
+ ID_OUI_FROM_DATABASE=GANA I&C CO., LTD
+
+OUI:10BD18
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:1100AA
+ ID_OUI_FROM_DATABASE=
+
+OUI:140708
+ ID_OUI_FROM_DATABASE=
+
+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:146E0A
+ ID_OUI_FROM_DATABASE=
+
+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: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
+
+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:18421D
+ ID_OUI_FROM_DATABASE=
+
+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:18550F
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+OUI:185933
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
+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: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: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
+
+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
+
+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
+
+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
+
+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:1CF4CA
+ ID_OUI_FROM_DATABASE=
+
+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: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
+
+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:205B2A
+ ID_OUI_FROM_DATABASE=
+
+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:20858C
+ ID_OUI_FROM_DATABASE=Assa
+
+OUI:208984
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD
+
+OUI:2091D9
+ ID_OUI_FROM_DATABASE=I&#39;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: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: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
+
+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:24BF74
+ ID_OUI_FROM_DATABASE=
+
+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 fuer professionelle Audiotechnik mbH
+
+OUI:28924A
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:2893FE
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:28940F
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:28C718
+ ID_OUI_FROM_DATABASE=Altierre
+
+OUI:28C914
+ ID_OUI_FROM_DATABASE=Taimag Corporation
+
+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:28EF01
+ ID_OUI_FROM_DATABASE=
+
+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: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 &amp; 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
+
+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
+
+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
+
+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: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: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
+
+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: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: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
+
+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: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:34AF2C
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+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: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: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:38458C
+ ID_OUI_FROM_DATABASE=MyCloud Technology corporation
+
+OUI:384608
+ ID_OUI_FROM_DATABASE=ZTE Corporation
+
+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=Panasonic Telecom Co.,Ltd
+
+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: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: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: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 &amp; 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: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: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:3CB87A
+ ID_OUI_FROM_DATABASE=
+
+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&amp;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
+
+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
+
+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
+
+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:40D855
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY
+
+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
+
+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: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
+
+OUI:44322A
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+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: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
+
+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
+
+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: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:48F317
+ ID_OUI_FROM_DATABASE=
+
+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:4C1FCC
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:4C2258
+ ID_OUI_FROM_DATABASE=cozybit, Inc.
+
+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: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: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: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
+
+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:505663
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:5057A8
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:50A6E3
+ ID_OUI_FROM_DATABASE=David Clark Company
+
+OUI:50A733
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+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: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: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:547398
+ ID_OUI_FROM_DATABASE=Toyo Electronics Corporation
+
+OUI:5474E6
+ ID_OUI_FROM_DATABASE=Webtech Wireless
+
+OUI:5475D0
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:54781A
+ ID_OUI_FROM_DATABASE=Cisco
+
+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
+
+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: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 &amp; telecommunication INC.
+
+OUI:580943
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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:586ED6
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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
+
+OUI:58BDA3
+ ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
+
+OUI:58BFEA
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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: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: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
+
+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: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: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ÜHENDISLIK ELEKTRONIK TICARET SANAYI Limited Þirketi
+
+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: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: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
+
+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
+
+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: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: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: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
+
+OUI:649FF7
+ ID_OUI_FROM_DATABASE=Kone OYj
+
+OUI:64A0E7
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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
+
+OUI:64D912
+ ID_OUI_FROM_DATABASE=Solidica, Inc.
+
+OUI:64D989
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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: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: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
+
+OUI:68BDAB
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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: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
+
+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
+
+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: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: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: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: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: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:706F81
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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
+
+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: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: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: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: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: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: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: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:7C7BE4
+ ID_OUI_FROM_DATABASE=Z&#39;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 &amp; 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: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: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: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: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: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:848F69
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:849000
+ ID_OUI_FROM_DATABASE=Arnold &amp; Richter Cine Technik
+
+OUI:8497B8
+ ID_OUI_FROM_DATABASE=Memjet Inc.
+
+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:84AF1F
+ ID_OUI_FROM_DATABASE=Beat System Service 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: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: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:8841C1
+ ID_OUI_FROM_DATABASE=ORBISAT DA AMAZONIA IND E AEROL SA
+
+OUI:8843E1
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:884B39
+ ID_OUI_FROM_DATABASE=Siemens AG, Healthcare Sector
+
+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: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
+
+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: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
+
+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: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:8C8401
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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:8CE748
+ ID_OUI_FROM_DATABASE=
+
+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: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: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: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 Froschl 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: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: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: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:980EE4
+ ID_OUI_FROM_DATABASE=
+
+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: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: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=Raychem International
+
+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: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: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: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
+
+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: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
+
+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: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: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&amp;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
+
+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: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
+
+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
+
+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: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
+
+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
+
+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
+
+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: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 &amp; 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: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: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=DISPL’AIRE 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: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
+
+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 &amp; 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: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: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
+
+OUI:ACA22C
+ ID_OUI_FROM_DATABASE=Baycity Technologies Ltd
+
+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:ACDE48
+ ID_OUI_FROM_DATABASE=
+
+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: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: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: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: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: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: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
+
+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: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
+
+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:B4E1EB
+ ID_OUI_FROM_DATABASE=
+
+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: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:B85AFE
+ ID_OUI_FROM_DATABASE=Handaer Communication Technology (Beijing) Co., Ltd
+
+OUI:B8616F
+ ID_OUI_FROM_DATABASE=Accton Wireless Broadband(AWB), Corp.
+
+OUI:B8621F
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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: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&amp;A
+
+OUI:B894D2
+ ID_OUI_FROM_DATABASE=Retail Innovation HTT AB
+
+OUI:B89674
+ ID_OUI_FROM_DATABASE=AllDSP GmbH &amp; 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
+
+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: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: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: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: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:C02250
+ ID_OUI_FROM_DATABASE=
+
+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:C058A7
+ ID_OUI_FROM_DATABASE=Pico Systems Co., Ltd.
+
+OUI:C05E79
+ ID_OUI_FROM_DATABASE=SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD
+
+OUI:C0626B
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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 Eletronicos 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: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 &amp; 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
+
+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: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:C45976
+ ID_OUI_FROM_DATABASE=Fugoo
+
+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
+
+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
+
+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
+
+OUI:C4823F
+ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd.
+
+OUI:C48508
+ ID_OUI_FROM_DATABASE=Intel Corporation
+
+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:C4E17C
+ ID_OUI_FROM_DATABASE=U2S co.
+
+OUI:C4E7BE
+ ID_OUI_FROM_DATABASE=SCSpro Co.,Ltd
+
+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: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
+
+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: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
+
+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:C8AACC
+ ID_OUI_FROM_DATABASE=
+
+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
+
+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: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:CC34D7
+ ID_OUI_FROM_DATABASE=GEWISS S.P.A.
+
+OUI:CC43E3
+ ID_OUI_FROM_DATABASE=Trump s.a.
+
+OUI:CC4BFB
+ ID_OUI_FROM_DATABASE=Hellberg Safety AB
+
+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: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: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
+
+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:D0542D
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
+OUI:D0574C
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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&amp;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: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
+
+OUI:D0CF5E
+ ID_OUI_FROM_DATABASE=Energy Micro AS
+
+OUI:D0D0FD
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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:D428B2
+ ID_OUI_FROM_DATABASE=ioBridge, Inc.
+
+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 &amp; 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
+
+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
+
+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:D4C1FC
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:D4C766
+ ID_OUI_FROM_DATABASE=Acentic GmbH
+
+OUI:D4CA6D
+ ID_OUI_FROM_DATABASE=Routerboard.com
+
+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
+
+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: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: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:D81BFE
+ ID_OUI_FROM_DATABASE=TWINLINX CORPORATION
+
+OUI:D81C14
+ ID_OUI_FROM_DATABASE=Compacta International, Ltd.
+
+OUI:D824BD
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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: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: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:DC7144
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
+
+OUI:DC7B94
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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 &amp; Softwareentwicklung
+
+OUI:E05FB9
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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: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: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: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:E0CB1D
+ ID_OUI_FROM_DATABASE=
+
+OUI:E0CB4E
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+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: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: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
+
+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: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
+
+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: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
+
+OUI:E8BA70
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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: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
+
+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:EC4476
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:EC4644
+ ID_OUI_FROM_DATABASE=TTK SAS
+
+OUI:EC4670
+ ID_OUI_FROM_DATABASE=Meinberg Funkuhren GmbH &amp; 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&amp;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
+
+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 &amp; 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:F02408
+ ID_OUI_FROM_DATABASE=Talaris (Sweden) AB
+
+OUI:F02572
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:F0264C
+ ID_OUI_FROM_DATABASE=Dr. Sigrist AG
+
+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:F04F7C
+ ID_OUI_FROM_DATABASE=
+
+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:F0A225
+ ID_OUI_FROM_DATABASE=
+
+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=Draegerwerk AG &amp;amp; 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:F0F755
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+OUI:F0F7B3
+ ID_OUI_FROM_DATABASE=Phorm
+
+OUI:F0F842
+ ID_OUI_FROM_DATABASE=KEEBOX, Inc.
+
+OUI:F0F9F7
+ ID_OUI_FROM_DATABASE=IES GmbH &amp; 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: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:F47F35
+ ID_OUI_FROM_DATABASE=Cisco Systems
+
+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
+
+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: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
+
+OUI:F4EC38
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
+
+OUI:F4FC32
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+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: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
+
+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:F8E4FB
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:F8E7B5
+ ID_OUI_FROM_DATABASE=uTech Engenharia e Automaçao 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: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: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: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: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
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
new file mode 100644
index 0000000000..421dec0337
--- /dev/null
+++ b/hwdb/20-acpi-vendor.hwdb
@@ -0,0 +1,6050 @@
+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=Adtek
+
+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: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: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:AMP*:
+ ID_VENDOR_FROM_DATABASE=AMP 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: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:AUO*:
+ ID_VENDOR_FROM_DATABASE=AU Optronics
+
+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:AVM*:
+ ID_VENDOR_FROM_DATABASE=AVM GmbH
+
+acpi:AVO*:
+ ID_VENDOR_FROM_DATABASE=Avocent Corporation
+
+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: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=Dr. Seufert 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:BOS*:
+ ID_VENDOR_FROM_DATABASE=BOS
+
+acpi:BPD*:
+ ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc.
+
+acpi:BPU*:
+ ID_VENDOR_FROM_DATABASE=Best Power
+
+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: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:BUF*:
+ ID_VENDOR_FROM_DATABASE=Yasuhiko Shirai Melco 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:CBI*:
+ ID_VENDOR_FROM_DATABASE=ComputerBoards Inc
+
+acpi:CBR*:
+ ID_VENDOR_FROM_DATABASE=Cebra Tech A/S
+
+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: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: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: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: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: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: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: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: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: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: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: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: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:DEC*:
+ ID_VENDOR_FROM_DATABASE=Digital Equipment Corporation
+
+acpi:DEI*:
+ ID_VENDOR_FROM_DATABASE=Deico Electronics
+
+acpi:DEL*:
+ ID_VENDOR_FROM_DATABASE=Dell
+
+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: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=Dearborn Group Technology
+
+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: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: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: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: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: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: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: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: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: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: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: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: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:ESC*:
+ ID_VENDOR_FROM_DATABASE=Eden Sistemas de Computacao S/A
+
+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: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: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: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: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:FER*:
+ ID_VENDOR_FROM_DATABASE=Ferranti Int'L
+
+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: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: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=Fellowes, 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: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:FTN*:
+ ID_VENDOR_FROM_DATABASE=Fountain Technologies Inc
+
+acpi:FTR*:
+ ID_VENDOR_FROM_DATABASE=Mediasonic
+
+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: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: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:GES*:
+ ID_VENDOR_FROM_DATABASE=GES Singapore Pte Ltd
+
+acpi:GFM*:
+ ID_VENDOR_FROM_DATABASE=GFMesstechnik GmbH
+
+acpi:GFN*:
+ ID_VENDOR_FROM_DATABASE=Gefen Inc.
+
+acpi:GIC*:
+ ID_VENDOR_FROM_DATABASE=General Inst. Corporation
+
+acpi:GIM*:
+ ID_VENDOR_FROM_DATABASE=Guillemont International
+
+acpi:GIS*:
+ ID_VENDOR_FROM_DATABASE=AT&T Global Info Solutions
+
+acpi:GJN*:
+ ID_VENDOR_FROM_DATABASE=Grand Junction Networks
+
+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: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:HAY*:
+ ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products Inc
+
+acpi:HCA*:
+ ID_VENDOR_FROM_DATABASE=DAT
+
+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=Hitachi Engineering Company 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: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: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: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: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:HSM*:
+ ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
+
+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: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 Corporation
+
+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: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:IDO*:
+ ID_VENDOR_FROM_DATABASE=IDEO Product Development
+
+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:IGC*:
+ ID_VENDOR_FROM_DATABASE=Intergate Pty Ltd
+
+acpi:IGM*:
+ ID_VENDOR_FROM_DATABASE=IGM Communi
+
+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: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: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: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: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=Liyama North America
+
+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:JAT*:
+ ID_VENDOR_FROM_DATABASE=Jaton Corporation
+
+acpi:JAZ*:
+ ID_VENDOR_FROM_DATABASE=Carrera Computer Inc (used as second pnpid)
+
+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: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: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: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: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:KFX*:
+ ID_VENDOR_FROM_DATABASE=Kofax Image Products
+
+acpi:KIS*:
+ ID_VENDOR_FROM_DATABASE=KiSS Technology A/S
+
+acpi:KMC*:
+ ID_VENDOR_FROM_DATABASE=Mitsumi Company 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: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: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: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: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: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: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:LPE*:
+ ID_VENDOR_FROM_DATABASE=El-PUSK Co., Ltd.
+
+acpi:LPI*:
+ ID_VENDOR_FROM_DATABASE=Design Technology
+
+acpi:LPL*:
+ ID_VENDOR_FROM_DATABASE=LG Philips
+
+acpi:LSC*:
+ ID_VENDOR_FROM_DATABASE=LifeSize Communications
+
+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: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: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: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: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: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: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: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:NAL*:
+ ID_VENDOR_FROM_DATABASE=Network Alchemy
+
+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: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: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: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: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: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:OTI*:
+ ID_VENDOR_FROM_DATABASE=Orchid Technology
+
+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: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: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: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:PHI*:
+ ID_VENDOR_FROM_DATABASE=DO NOT USE - PHI
+
+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:PLM*:
+ ID_VENDOR_FROM_DATABASE=PROLINK Microsystems Corp.
+
+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: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: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: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: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: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: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:RDI*:
+ ID_VENDOR_FROM_DATABASE=Rainbow Displays, Inc.
+
+acpi:RDM*:
+ ID_VENDOR_FROM_DATABASE=Tremon Enterprises Company Ltd
+
+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: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:RGL*:
+ ID_VENDOR_FROM_DATABASE=Robertson Geologging Ltd
+
+acpi:RHM*:
+ ID_VENDOR_FROM_DATABASE=Rohm 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: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: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: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: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: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: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: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: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:STW*:
+ ID_VENDOR_FROM_DATABASE=Starwin Inc.
+
+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:SYC*:
+ ID_VENDOR_FROM_DATABASE=Sysmic
+
+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: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: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=(none)
+
+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: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:TRU*:
+ ID_VENDOR_FROM_DATABASE=Aashima Technology B.V.
+
+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: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: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: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: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:UND*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNE*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNF*:
+ 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: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: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: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:VNC*:
+ ID_VENDOR_FROM_DATABASE=Vinca Corporation
+
+acpi:VOB*:
+ ID_VENDOR_FROM_DATABASE=MaxData Computer AG
+
+acpi:VPR*:
+ ID_VENDOR_FROM_DATABASE=Best Buy
+
+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:VTS*:
+ ID_VENDOR_FROM_DATABASE=VTech Computers Ltd
+
+acpi:VTV*:
+ ID_VENDOR_FROM_DATABASE=VATIV Technologies
+
+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: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: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:WYS*:
+ ID_VENDOR_FROM_DATABASE=Wyse Technology
+
+acpi:WYT*:
+ ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
+
+acpi:XAC*:
+ ID_VENDOR_FROM_DATABASE=XAC Automation Corp
+
+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: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=ZTEIC DESIGN CO., LTD.
+
+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:ZTI*:
+ ID_VENDOR_FROM_DATABASE=Zoom Telephonics Inc
+
+acpi:ZTM*:
+ ID_VENDOR_FROM_DATABASE=ZT Group Int'l Inc.
+
+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-pci-classes.hwdb b/hwdb/20-pci-classes.hwdb
new file mode 100644
index 0000000000..0541eb73e9
--- /dev/null
+++ b/hwdb/20-pci-classes.hwdb
@@ -0,0 +1,531 @@
+# This file is part of systemd.
+#
+# Data imported and updated 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
index 0000000000..eb842b8d2c
--- /dev/null
+++ b/hwdb/20-pci-vendor-product.hwdb
@@ -0,0 +1,63618 @@
+# This file is part of systemd.
+#
+# Data imported and updated 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:v00000403*
+ ID_VENDOR_FROM_DATABASE=Future Technology Devices International Ltd
+
+pci:v00000432*
+ ID_VENDOR_FROM_DATABASE=SCM Microsystems, Inc.
+
+pci:v00000432d00000001*
+ ID_PRODUCT_FROM_DATABASE=Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
+
+pci:v00000482*
+ ID_VENDOR_FROM_DATABASE=Kyocera
+
+pci:v000004B3*
+ ID_VENDOR_FROM_DATABASE=IBM Corp.
+
+pci:v000004B3d00004001*
+ ID_PRODUCT_FROM_DATABASE=Remote System Administration device [RSA2]
+
+pci:v0000050D*
+ ID_VENDOR_FROM_DATABASE=Belkin
+
+pci:v000005A9*
+ ID_VENDOR_FROM_DATABASE=OmniVision
+
+pci:v000005A9d00008519*
+ ID_PRODUCT_FROM_DATABASE=OV519 series
+
+pci:v000005E3*
+ ID_VENDOR_FROM_DATABASE=CyberDoor
+
+pci:v000005E3d00000701*
+ ID_PRODUCT_FROM_DATABASE=CBD516
+
+pci:v0000066F*
+ ID_VENDOR_FROM_DATABASE=SigmaTel
+
+pci:v0000066Fd00003410*
+ ID_PRODUCT_FROM_DATABASE=SMTP3410
+
+pci:v0000066Fd00003500*
+ ID_PRODUCT_FROM_DATABASE=SMTP3500
+
+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:v0000069D*
+ ID_VENDOR_FROM_DATABASE=Hughes Network Systems (HNS)
+
+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:v00001000d0000005Bsv00001000sd00009268*
+ ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9265CV-8i / 9270CV-8i
+
+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: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: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: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: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: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: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=Hudson SATA Controller [IDE mode]
+
+pci:v00001022d00007801*
+ ID_PRODUCT_FROM_DATABASE=Hudson SATA Controller [AHCI mode]
+
+pci:v00001022d00007802*
+ ID_PRODUCT_FROM_DATABASE=Hudson SATA Controller [RAID mode]
+
+pci:v00001022d00007803*
+ ID_PRODUCT_FROM_DATABASE=Hudson SATA Controller [RAID mode]
+
+pci:v00001022d00007804*
+ ID_PRODUCT_FROM_DATABASE=Hudson SATA Controller [AHCI mode]
+
+pci:v00001022d00007805*
+ ID_PRODUCT_FROM_DATABASE=Hudson SATA Controller [RAID mode]
+
+pci:v00001022d00007806*
+ ID_PRODUCT_FROM_DATABASE=Hudson SD Flash Controller
+
+pci:v00001022d00007807*
+ ID_PRODUCT_FROM_DATABASE=Hudson USB OHCI Controller
+
+pci:v00001022d00007808*
+ ID_PRODUCT_FROM_DATABASE=Hudson USB EHCI Controller
+
+pci:v00001022d00007809*
+ ID_PRODUCT_FROM_DATABASE=Hudson USB OHCI Controller
+
+pci:v00001022d0000780B*
+ ID_PRODUCT_FROM_DATABASE=Hudson SMBus Controller
+
+pci:v00001022d0000780C*
+ ID_PRODUCT_FROM_DATABASE=Hudson IDE Controller
+
+pci:v00001022d0000780D*
+ ID_PRODUCT_FROM_DATABASE=Hudson Azalia Controller
+
+pci:v00001022d0000780E*
+ ID_PRODUCT_FROM_DATABASE=Hudson LPC Bridge
+
+pci:v00001022d0000780F*
+ ID_PRODUCT_FROM_DATABASE=Hudson PCI Bridge
+
+pci:v00001022d00007812*
+ ID_PRODUCT_FROM_DATABASE=Hudson 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: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: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: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:v0000103Cd0000780D*
+ ID_PRODUCT_FROM_DATABASE=Hudson Azalia Controller (rev 01) - Soundcard
+
+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: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: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: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:v000010B5d0000D44D*
+ ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
+
+pci:v000010B5d0000D44Dsv000010B5sd000017F6*
+ ID_PRODUCT_FROM_DATABASE=entVoice E1 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: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: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: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: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: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=GF106 [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=X-Fi Titanium series [EMU20k2]
+
+pci:v00001102d0000000Bsv00001102sd00000041*
+ ID_PRODUCT_FROM_DATABASE=SB X-Fi Titanium PCI-e [SB0880]
+
+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: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 Telesyn International
+
+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:v000014C1d00000008sv000014C1sd0000000B*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE-8B2
+
+pci:v000014C1d00000008sv000014C1sd0000000C*
+ ID_PRODUCT_FROM_DATABASE=10G-PCIE2-8B2
+
+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: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: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: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: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=Fastcom ESCC-PCI-335
+
+pci:v000018F7d00000002*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 422/4-PCI-335
+
+pci:v000018F7d00000003*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 232/4-1M-PCI
+
+pci:v000018F7d00000004*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 422/2-PCI-335
+
+pci:v000018F7d00000005*
+ ID_PRODUCT_FROM_DATABASE=Fastcom IGESCC-PCI-ISO/1
+
+pci:v000018F7d0000000A*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 232/4-PCI-335
+
+pci:v000018F7d0000000B*
+ ID_PRODUCT_FROM_DATABASE=Fastcom 232/8-PCI-335 Async 8-Port RS-232 Serial PCI Adapter
+
+pci:v000018F7d0000000F*
+ ID_PRODUCT_FROM_DATABASE=Fastcom FSCC
+
+pci:v000018F7d00000010*
+ ID_PRODUCT_FROM_DATABASE=Fastcom GSCC
+
+pci:v000018F7d00000011*
+ ID_PRODUCT_FROM_DATABASE=Fastcom QSSB
+
+pci:v000018F7d00000014*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC
+
+pci:v000018F7d00000015*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC-104
+
+pci:v000018F7d00000016*
+ ID_PRODUCT_FROM_DATABASE=Fastcom FSCC-232 Sync/Async 2-Port RS-232 Serial PCI Adapter (F-Core)
+
+pci:v000018F7d00000017*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC-104-NOUART
+
+pci:v000018F7d00000018*
+ ID_PRODUCT_FROM_DATABASE=Fastcom SuperFSCC/4 Sync/Async 4-Port RS-422 Serial PCI Adapter with DMA (F-Core)
+
+pci:v000018F7d00000019*
+ ID_PRODUCT_FROM_DATABASE=SuperFSCC with soft UARTs
+
+pci:v000018F7d0000001A*
+ ID_PRODUCT_FROM_DATABASE=Fastcom SuperFSCC-104-LVDS Sync/Async 2-Port RS-644 Serial PC/104+ Adapter with DMA (F-Core)
+
+pci:v000018F7d0000001B*
+ ID_PRODUCT_FROM_DATABASE=Fastcom FSCC/4 Sync/Async 4-Port RS-422 Serial PCI Adapter (F-Core)
+
+pci:v000018F7d0000001C*
+ ID_PRODUCT_FROM_DATABASE=Fastcom SuperFSCC/4-LVDSSync/Async 4-Port RS-644 Serial PCI Adapter with DMA (F-Core)
+
+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: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:v00008086d00000154*
+ ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor DRAM Controller
+
+pci:v00008086d00000154sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+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: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:v00008086d00000326sv00001775sd00001100*
+ ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer
+
+pci:v00008086d00000327*
+ ID_PRODUCT_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B
+
+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:v00008086d00000D0C*
+ ID_PRODUCT_FROM_DATABASE=Crystal Well HD Audio Controller
+
+pci:v00008086d00000E00*
+ ID_PRODUCT_FROM_DATABASE=Ivytown DMI2
+
+pci:v00008086d00000E01*
+ ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port in DMI2 Mode
+
+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 [Wharton Stony Lake]
+
+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 [Badger Flat]
+
+pci:v00008086d00001523sv0000103Csd000018D1*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter
+
+pci:v00008086d00001523sv0000103Csd0000339F*
+ ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 4-port 366M Adapter [Vaca Key]
+
+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: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: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: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: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:v00008086d00001E12*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2
+
+pci:v00008086d00001E12sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+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:v00008086d00001E22*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller
+
+pci:v00008086d00001E22sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E24*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller
+
+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:v00008086d00001E2D*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2
+
+pci:v00008086d00001E2Dsv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+pci:v00008086d00001E31*
+ ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller
+
+pci:v00008086d00001E31sv00001043sd00001477*
+ ID_PRODUCT_FROM_DATABASE=N56VZ
+
+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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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:v00008086d00002692*
+ ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 2
+
+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: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: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: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: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: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: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: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
index 0000000000..064cf9b466
--- /dev/null
+++ b/hwdb/20-usb-classes.hwdb
@@ -0,0 +1,339 @@
+# This file is part of systemd.
+#
+# Data imported and updated 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
index 0000000000..e197ea2dd8
--- /dev/null
+++ b/hwdb/20-usb-vendor-product.hwdb
@@ -0,0 +1,47304 @@
+# This file is part of systemd.
+#
+# Data imported and updated 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: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: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: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: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: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: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=Lexmark 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: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: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: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: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
+
+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=BT 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
+
+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=LS1 Laser Mouse, corded
+
+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: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: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: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: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:v04A9p312D*
+ ID_PRODUCT_FROM_DATABASE=Elura 100
+
+usb:v04A9p3138*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A710 IS
+
+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: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:v04A9p3192*
+ ID_PRODUCT_FROM_DATABASE=PowerShot SX110 IS
+
+usb:v04A9p319A*
+ ID_PRODUCT_FROM_DATABASE=EOS 7D
+
+usb:v04A9p31AD*
+ ID_PRODUCT_FROM_DATABASE=PowerShot E1
+
+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: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: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: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:v04A9p324A*
+ ID_PRODUCT_FROM_DATABASE=PowerShot A2300
+
+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: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: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: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: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: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: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: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=Bamboo Fun 4x5
+
+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
+
+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: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: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: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: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: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: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 [ednet]
+
+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: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: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: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: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: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: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: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: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=Digital Camera
+
+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: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: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: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=64MB QDI U2 DISK
+
+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:v091Ep2353*
+ ID_PRODUCT_FROM_DATABASE=Nüvi 205T
+
+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: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=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=Netcom Systems
+
+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: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: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: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: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: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: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: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:v0B05p4D00*
+ ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201
+
+usb:v0B05p4D01*
+ ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201 (debug mode)
+
+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: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: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: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=Card Reader
+
+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=Mass Storage Device
+
+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:v0BDAp0138*
+ ID_PRODUCT_FROM_DATABASE=Card reader
+
+usb:v0BDAp0139*
+ ID_PRODUCT_FROM_DATABASE=Card reader
+
+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=Digital Media Card Reader
+
+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: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: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: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: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: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: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: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: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: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: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: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: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: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: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=Unknown
+
+usb:v13BAp0017*
+ ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter
+
+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=Shintaro SH23SDOCK Hard Drive Docker [INIC-1608L]
+
+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: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: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: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: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: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: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:v16D0p0504*
+ ID_PRODUCT_FROM_DATABASE=RETRO Innovations ZoomFloppy
+
+usb:v16D0p054B*
+ ID_PRODUCT_FROM_DATABASE=GrauTec ReelBox OLED Display (external)
+
+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: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
+
+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
+
+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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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
+
+usb:v1949p0002*
+ ID_PRODUCT_FROM_DATABASE=Amazon Kindle
+
+usb:v1949p0004*
+ ID_PRODUCT_FROM_DATABASE=Amazon Kindle 3/4
+
+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: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: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: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:v19D2p0172*
+ ID_PRODUCT_FROM_DATABASE=AX226 WIMAX MODEM (After Modeswitch)
+
+usb:v19D2p1203*
+ ID_PRODUCT_FROM_DATABASE=MF691 [ T-Mobile webConnect Rocket 2.0]
+
+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:v1A32*
+ ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc.
+
+usb:v1A32p0304*
+ ID_PRODUCT_FROM_DATABASE=802.11n Wireless LAN Card
+
+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:v1A61*
+ ID_VENDOR_FROM_DATABASE=Abbott Diabetes Care
+
+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: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: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:v1A90*
+ ID_VENDOR_FROM_DATABASE=Corsair Voyager GT 16GB
+
+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: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: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:v1B1C*
+ ID_VENDOR_FROM_DATABASE=Corsair
+
+usb:v1B1Cp0890*
+ ID_PRODUCT_FROM_DATABASE=Flash Padlock
+
+usb:v1B1Cp0A00*
+ ID_PRODUCT_FROM_DATABASE=SP2500 Speakers
+
+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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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:v1F4D*
+ ID_VENDOR_FROM_DATABASE=G-Tek Electronics Group
+
+usb:v1F4DpB803*
+ ID_PRODUCT_FROM_DATABASE=Lifeview LV5TDLX DVB-T [RTL2832U]
+
+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: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: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=10/100 Ethernet
+
+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:v2001p3C19*
+ ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A3) [Ralink RT5370]
+
+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: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:v2019p4903*
+ ID_PRODUCT_FROM_DATABASE=GW-USFang300 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: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:v2019pED17*
+ ID_PRODUCT_FROM_DATABASE=GW-USValue-EZ 802.11n Wireless Adapter [Realtek RTL8188CUS]
+
+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: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
index 0000000000..b21a3d8f59
--- /dev/null
+++ b/hwdb/ids-update.pl
@@ -0,0 +1,239 @@
+#!/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 and updated 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(INP);
+ close(OUTP);
+}
+
+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 and updated 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(INP);
+ close(OUTP);
+}
+
+sub pci_vendor {
+ my $vendor;
+ my $device;
+
+ open(IN, "<", "usb.ids");
+ open(IN, "<", "pci.ids");
+ open(OUT, ">", "20-pci-vendor-product.hwdb");
+ print(OUT "# This file is part of systemd.\n" .
+ "#\n" .
+ "# Data imported and updated 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(INP);
+ close(OUTP);
+}
+
+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 and updated 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(INP);
+ close(OUTP);
+}
+
+sub oui {
+ open(IN, "<", "oui.txt");
+ open(OUT, ">", "20-OUI.hwdb");
+ print(OUT "# This file is part of systemd.\n" .
+ "#\n" .
+ "# Data imported and updated from: http://standards.ieee.org/develop/regauth/oui/oui.txt\n");
+
+ 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;
+ print(OUT "\n");
+ print(OUT "OUI:" . $vendor . "\n");
+ print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
+ }
+ }
+
+ close(INP);
+ close(OUTP);
+}
+
+usb_vendor();
+usb_classes();
+
+pci_vendor();
+pci_classes();
+
+oui();
diff --git a/introspect.awk b/introspect.awk
new file mode 100644
index 0000000000..593191384a
--- /dev/null
+++ b/introspect.awk
@@ -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
index 0000000000..3a7654d735
--- /dev/null
+++ b/keymaps-force-release/common-volume-keys
@@ -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
index 0000000000..18e9bdee66
--- /dev/null
+++ b/keymaps-force-release/dell-touchpad
@@ -0,0 +1 @@
+0x9E
diff --git a/keymaps-force-release/dell-xps b/keymaps-force-release/dell-xps
new file mode 100644
index 0000000000..69f7899ad7
--- /dev/null
+++ b/keymaps-force-release/dell-xps
@@ -0,0 +1 @@
+0x8C
diff --git a/keymaps-force-release/hp-other b/keymaps-force-release/hp-other
new file mode 100644
index 0000000000..6621370095
--- /dev/null
+++ b/keymaps-force-release/hp-other
@@ -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-90x3a b/keymaps-force-release/samsung-90x3a
new file mode 100644
index 0000000000..65707effb7
--- /dev/null
+++ b/keymaps-force-release/samsung-90x3a
@@ -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-force-release/samsung-other b/keymaps-force-release/samsung-other
new file mode 100644
index 0000000000..c51123a0b6
--- /dev/null
+++ b/keymaps-force-release/samsung-other
@@ -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/acer b/keymaps/acer
new file mode 100644
index 0000000000..4e7c297dea
--- /dev/null
+++ b/keymaps/acer
@@ -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
index 0000000000..3ff9de3f32
--- /dev/null
+++ b/keymaps/acer-aspire_5720
@@ -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
index 0000000000..633c4e854c
--- /dev/null
+++ b/keymaps/acer-aspire_5920g
@@ -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
index 0000000000..699c954b4e
--- /dev/null
+++ b/keymaps/acer-aspire_6920
@@ -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
index 0000000000..fb27bfb4f5
--- /dev/null
+++ b/keymaps/acer-aspire_8930
@@ -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
index 0000000000..bfef4cf868
--- /dev/null
+++ b/keymaps/acer-travelmate_c300
@@ -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
index 0000000000..2a5995f982
--- /dev/null
+++ b/keymaps/asus
@@ -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
index 0000000000..5fbc573aa4
--- /dev/null
+++ b/keymaps/compaq-e_evo
@@ -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
index 0000000000..4f907b3eef
--- /dev/null
+++ b/keymaps/dell
@@ -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
index 0000000000..39872f559d
--- /dev/null
+++ b/keymaps/dell-latitude-xt2
@@ -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
index 0000000000..4823a832f5
--- /dev/null
+++ b/keymaps/everex-xt5000
@@ -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
index 0000000000..9b8b36a170
--- /dev/null
+++ b/keymaps/fujitsu-amilo_li_2732
@@ -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
index 0000000000..f7b0c52444
--- /dev/null
+++ b/keymaps/fujitsu-amilo_pa_2548
@@ -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
index 0000000000..d2e38cbb23
--- /dev/null
+++ b/keymaps/fujitsu-amilo_pro_edition_v3505
@@ -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
index 0000000000..43e3199d59
--- /dev/null
+++ b/keymaps/fujitsu-amilo_pro_v3205
@@ -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
index 0000000000..1419bd9b5e
--- /dev/null
+++ b/keymaps/fujitsu-amilo_si_1520
@@ -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
index 0000000000..d3d056b366
--- /dev/null
+++ b/keymaps/fujitsu-esprimo_mobile_v5
@@ -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
index 0000000000..52c70c50cb
--- /dev/null
+++ b/keymaps/fujitsu-esprimo_mobile_v6
@@ -0,0 +1,2 @@
+0xCE brightnessup
+0xEF brightnessdown
diff --git a/keymaps/genius-slimstar-320 b/keymaps/genius-slimstar-320
new file mode 100644
index 0000000000..d0a3656dd8
--- /dev/null
+++ b/keymaps/genius-slimstar-320
@@ -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
index 0000000000..4461fa2ce5
--- /dev/null
+++ b/keymaps/hewlett-packard
@@ -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
index 0000000000..41ad2e9b5a
--- /dev/null
+++ b/keymaps/hewlett-packard-2510p_2530p
@@ -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
index 0000000000..42007c5483
--- /dev/null
+++ b/keymaps/hewlett-packard-compaq_elitebook
@@ -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
index 0000000000..3d3cefc8e6
--- /dev/null
+++ b/keymaps/hewlett-packard-pavilion
@@ -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
index 0000000000..1df39dcbd2
--- /dev/null
+++ b/keymaps/hewlett-packard-presario-2100
@@ -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
index 0000000000..d19005ab90
--- /dev/null
+++ b/keymaps/hewlett-packard-tablet
@@ -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
index 0000000000..36a690fcf6
--- /dev/null
+++ b/keymaps/hewlett-packard-tx2
@@ -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
index 0000000000..e0c2a1a859
--- /dev/null
+++ b/keymaps/hewlett-packard_elitebook-8440p
@@ -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
index 0000000000..027e50bf88
--- /dev/null
+++ b/keymaps/ibm-thinkpad-usb-keyboard-trackpoint
@@ -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
index 0000000000..4a8b4ba5a7
--- /dev/null
+++ b/keymaps/inventec-symphony_6.0_7.0
@@ -0,0 +1,2 @@
+0xF3 prog2
+0xF4 prog1
diff --git a/keymaps/lenovo-3000 b/keymaps/lenovo-3000
new file mode 100644
index 0000000000..5bd165654a
--- /dev/null
+++ b/keymaps/lenovo-3000
@@ -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
index 0000000000..fc339839f2
--- /dev/null
+++ b/keymaps/lenovo-ideapad
@@ -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
index 0000000000..47e8846a68
--- /dev/null
+++ b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint
@@ -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
index 0000000000..31ea3b2c70
--- /dev/null
+++ b/keymaps/lenovo-thinkpad_x200_tablet
@@ -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
index 0000000000..6fd16b5662
--- /dev/null
+++ b/keymaps/lenovo-thinkpad_x6_tablet
@@ -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
index 0000000000..ba08cba3fe
--- /dev/null
+++ b/keymaps/lg-x110
@@ -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
index 0000000000..caa5d5d310
--- /dev/null
+++ b/keymaps/logitech-wave
@@ -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
index 0000000000..a10dad5e4d
--- /dev/null
+++ b/keymaps/logitech-wave-cordless
@@ -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
index 0000000000..e7aa02206c
--- /dev/null
+++ b/keymaps/logitech-wave-pro-cordless
@@ -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
index 0000000000..c0e4f77af4
--- /dev/null
+++ b/keymaps/maxdata-pro_7000
@@ -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
index 0000000000..5a76c76799
--- /dev/null
+++ b/keymaps/medion-fid2060
@@ -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
index 0000000000..c3b5dfa60b
--- /dev/null
+++ b/keymaps/medionnb-a555
@@ -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
index 0000000000..4a438698ed
--- /dev/null
+++ b/keymaps/micro-star
@@ -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
index 0000000000..773e0b3e82
--- /dev/null
+++ b/keymaps/module-asus-w3j
@@ -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
index 0000000000..a92dfa2506
--- /dev/null
+++ b/keymaps/module-ibm
@@ -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
index 0000000000..8e38883091
--- /dev/null
+++ b/keymaps/module-lenovo
@@ -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
index 0000000000..7c000131d1
--- /dev/null
+++ b/keymaps/module-sony
@@ -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
index 0000000000..596a34258a
--- /dev/null
+++ b/keymaps/module-sony-old
@@ -0,0 +1,2 @@
+0x06 battery
+0x07 mute
diff --git a/keymaps/module-sony-vgn b/keymaps/module-sony-vgn
new file mode 100644
index 0000000000..c8ba001516
--- /dev/null
+++ b/keymaps/module-sony-vgn
@@ -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
index 0000000000..681082c59e
--- /dev/null
+++ b/keymaps/module-sony-vpc
@@ -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
index 0000000000..34434a121d
--- /dev/null
+++ b/keymaps/olpc-xo
@@ -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
index 0000000000..ee864ade4d
--- /dev/null
+++ b/keymaps/onkyo
@@ -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
index 0000000000..b7f4851abe
--- /dev/null
+++ b/keymaps/oqo-model2
@@ -0,0 +1,5 @@
+0x8E wlan
+0xF0 switchvideomode
+0xF1 mute
+0xF2 volumedown
+0xF3 volumeup
diff --git a/keymaps/samsung-90x3a b/keymaps/samsung-90x3a
new file mode 100644
index 0000000000..3b65735fa0
--- /dev/null
+++ b/keymaps/samsung-90x3a
@@ -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-other b/keymaps/samsung-other
new file mode 100644
index 0000000000..3ac0c2f10c
--- /dev/null
+++ b/keymaps/samsung-other
@@ -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-sq1us b/keymaps/samsung-sq1us
new file mode 100644
index 0000000000..ea2141ef84
--- /dev/null
+++ b/keymaps/samsung-sq1us
@@ -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
index 0000000000..9d954ee415
--- /dev/null
+++ b/keymaps/samsung-sx20s
@@ -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
index 0000000000..22007be71b
--- /dev/null
+++ b/keymaps/toshiba-satellite_a100
@@ -0,0 +1,2 @@
+0xA4 stopcd
+0xB2 www
diff --git a/keymaps/toshiba-satellite_a110 b/keymaps/toshiba-satellite_a110
new file mode 100644
index 0000000000..1429409351
--- /dev/null
+++ b/keymaps/toshiba-satellite_a110
@@ -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
index 0000000000..ae8e34941b
--- /dev/null
+++ b/keymaps/toshiba-satellite_m30x
@@ -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
index 0000000000..cf72fda47b
--- /dev/null
+++ b/keymaps/zepto-znote
@@ -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
index 0000000000..cf35a86e88
--- /dev/null
+++ b/m4/.gitignore
@@ -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
index 0000000000..ccf8afc0aa
--- /dev/null
+++ b/m4/acx_libwrap.m4
@@ -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
index 0000000000..f0bcf24211
--- /dev/null
+++ b/m4/attributes.m4
@@ -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
index 0000000000..eaf7019a2b
--- /dev/null
+++ b/make-directive-index.py
@@ -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
index 0000000000..56f38ce413
--- /dev/null
+++ b/make-man-index.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- 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
index 0000000000..cf8c17cb95
--- /dev/null
+++ b/man/.gitignore
@@ -0,0 +1 @@
+/systemd.directives.xml
diff --git a/man/Makefile b/man/Makefile
new file mode 120000
index 0000000000..bd1047548b
--- /dev/null
+++ b/man/Makefile
@@ -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
index 0000000000..07ae0ac231
--- /dev/null
+++ b/man/binfmt.d.xml
@@ -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
index 0000000000..4cc4bafab7
--- /dev/null
+++ b/man/bootup.xml
@@ -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
index 0000000000..2a839944dc
--- /dev/null
+++ b/man/crypttab.xml
@@ -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
index 0000000000..906ddc5572
--- /dev/null
+++ b/man/custom-html.xsl
@@ -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
index 0000000000..197138e51d
--- /dev/null
+++ b/man/daemon.xml
@@ -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 reparented 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
index 0000000000..8473965194
--- /dev/null
+++ b/man/halt.xml
@@ -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
index 0000000000..84a2961664
--- /dev/null
+++ b/man/hostname.xml
@@ -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
index 0000000000..c36f522c8e
--- /dev/null
+++ b/man/hostnamectl.xml
@@ -0,0 +1,228 @@
+<?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 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 the
+ system form factor 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
index 0000000000..026bb22940
--- /dev/null
+++ b/man/journalctl.xml
@@ -0,0 +1,533 @@
+<?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>--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>--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 ommitted, 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>--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
index 0000000000..86c9869e51
--- /dev/null
+++ b/man/journald.conf.xml
@@ -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 other's
+ limit. 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
index 0000000000..27f0d4036f
--- /dev/null
+++ b/man/kernel-command-line.xml
@@ -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 paramaters 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
index 0000000000..06c0af0bf7
--- /dev/null
+++ b/man/locale.conf.xml
@@ -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
index 0000000000..33508cffe5
--- /dev/null
+++ b/man/localectl.xml
@@ -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
index 0000000000..88c84a3682
--- /dev/null
+++ b/man/localtime.xml
@@ -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
index 0000000000..5dbc1f6967
--- /dev/null
+++ b/man/loginctl.xml
@@ -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
index 0000000000..df15d51b5f
--- /dev/null
+++ b/man/logind.conf.xml
@@ -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
index 0000000000..7d424b705b
--- /dev/null
+++ b/man/machine-id.xml
@@ -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
index 0000000000..b310d71334
--- /dev/null
+++ b/man/machine-info.xml
@@ -0,0 +1,154 @@
+<?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>
+
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <programlisting>PRETTY_HOSTNAME="Lennart's Computer"
+ICON_NAME=computer-laptop</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
index 0000000000..bcc4d12561
--- /dev/null
+++ b/man/modules-load.d.xml
@@ -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
index 0000000000..98320efe31
--- /dev/null
+++ b/man/os-release.xml
@@ -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
index 0000000000..2d2f191487
--- /dev/null
+++ b/man/pam_systemd.xml
@@ -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="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>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
index 0000000000..02d5371c5d
--- /dev/null
+++ b/man/runlevel.xml
@@ -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
index 0000000000..a3bf662fe9
--- /dev/null
+++ b/man/sd-daemon.xml
@@ -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
index 0000000000..ac2000e275
--- /dev/null
+++ b/man/sd-id128.xml
@@ -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
index 0000000000..1beb9a5c7d
--- /dev/null
+++ b/man/sd-journal.xml
@@ -0,0 +1,130 @@
+<?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>
+ 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>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
index 0000000000..c02ad0c146
--- /dev/null
+++ b/man/sd-login.xml
@@ -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
index 0000000000..cebaa5da2b
--- /dev/null
+++ b/man/sd-readahead.xml
@@ -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
index 0000000000..34f2cbfbc8
--- /dev/null
+++ b/man/sd_booted.xml
@@ -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
index 0000000000..17adcef745
--- /dev/null
+++ b/man/sd_get_seats.xml
@@ -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
index 0000000000..039c1dd64c
--- /dev/null
+++ b/man/sd_id128_get_machine.xml
@@ -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
index 0000000000..be74937dd0
--- /dev/null
+++ b/man/sd_id128_randomize.xml
@@ -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
index 0000000000..ec8b263e0d
--- /dev/null
+++ b/man/sd_id128_to_string.xml
@@ -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
index 0000000000..595c8f112d
--- /dev/null
+++ b/man/sd_is_fifo.xml
@@ -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
index 0000000000..ad2486d749
--- /dev/null
+++ b/man/sd_journal_add_match.xml
@@ -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_cursor.xml b/man/sd_journal_get_cursor.xml
new file mode 100644
index 0000000000..354168bee2
--- /dev/null
+++ b/man/sd_journal_get_cursor.xml
@@ -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
index 0000000000..ed014cb509
--- /dev/null
+++ b/man/sd_journal_get_cutoff_realtime_usec.xml
@@ -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
index 0000000000..6470f19cc6
--- /dev/null
+++ b/man/sd_journal_get_data.xml
@@ -0,0 +1,201 @@
+<?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>
+ <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>
+
+ </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
+ '='.</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>
+ </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.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The <function>sd_journal_get_data()</function>,
+ <function>sd_journal_enumerate_data()</function> and
+ <function>sd_journal_restart_data()</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
index 0000000000..189d21352b
--- /dev/null
+++ b/man/sd_journal_get_fd.xml
@@ -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
index 0000000000..515932c6d8
--- /dev/null
+++ b/man/sd_journal_get_realtime_usec.xml
@@ -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
index 0000000000..14eb1e2b79
--- /dev/null
+++ b/man/sd_journal_get_usage.xml
@@ -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
index 0000000000..9b1cb1fc46
--- /dev/null
+++ b/man/sd_journal_next.xml
@@ -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
index 0000000000..06d0ccfd12
--- /dev/null
+++ b/man/sd_journal_open.xml
@@ -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>int <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
index 0000000000..7742268f5d
--- /dev/null
+++ b/man/sd_journal_print.xml
@@ -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
index 0000000000..f2f8af0eb5
--- /dev/null
+++ b/man/sd_journal_query_unique.xml
@@ -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_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 '='.</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
index 0000000000..3716c5d367
--- /dev/null
+++ b/man/sd_journal_seek_head.xml
@@ -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
index 0000000000..4407296b40
--- /dev/null
+++ b/man/sd_journal_stream_fd.xml
@@ -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
index 0000000000..b891b6b039
--- /dev/null
+++ b/man/sd_listen_fds.xml
@@ -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
index 0000000000..35cb6b368b
--- /dev/null
+++ b/man/sd_login_monitor_new.xml
@@ -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
index 0000000000..75edeeadf3
--- /dev/null
+++ b/man/sd_notify.xml
@@ -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
index 0000000000..9517795f78
--- /dev/null
+++ b/man/sd_pid_get_session.xml
@@ -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
index 0000000000..a1fc6f178f
--- /dev/null
+++ b/man/sd_readahead.xml
@@ -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
index 0000000000..b1d6d20edf
--- /dev/null
+++ b/man/sd_seat_get_active.xml
@@ -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
index 0000000000..a9107cb95f
--- /dev/null
+++ b/man/sd_session_is_active.xml
@@ -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
index 0000000000..b7bc944b14
--- /dev/null
+++ b/man/sd_uid_get_state.xml
@@ -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
index 0000000000..d54fcb25ab
--- /dev/null
+++ b/man/shutdown.xml
@@ -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
index 0000000000..69aac8cab7
--- /dev/null
+++ b/man/sysctl.d.xml
@@ -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
index 0000000000..31f3b1a909
--- /dev/null
+++ b/man/systemctl.xml
@@ -0,0 +1,1268 @@
+<?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>
+ </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>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>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
index 0000000000..c2ff9cc5bd
--- /dev/null
+++ b/man/systemd-analyze.xml
@@ -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
index 0000000000..6c87feb179
--- /dev/null
+++ b/man/systemd-ask-password-console.service.xml
@@ -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
index 0000000000..7b0b9ab809
--- /dev/null
+++ b/man/systemd-ask-password.xml
@@ -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
index 0000000000..1db735a826
--- /dev/null
+++ b/man/systemd-binfmt.service.xml
@@ -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
index 0000000000..cac275b453
--- /dev/null
+++ b/man/systemd-cat.xml
@@ -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
index 0000000000..4b6ee93b4e
--- /dev/null
+++ b/man/systemd-cgls.xml
@@ -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
index 0000000000..7a34512b21
--- /dev/null
+++ b/man/systemd-cgtop.xml
@@ -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
index 0000000000..8b54b90999
--- /dev/null
+++ b/man/systemd-coredumpctl.xml
@@ -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 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 <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg> <arg choice="opt" rep="repeat">PID|COMM|EXE|MATCH</arg></command>
+ </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
index 0000000000..49d4d5545b
--- /dev/null
+++ b/man/systemd-cryptsetup-generator.xml
@@ -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
index 0000000000..abbb9d78f2
--- /dev/null
+++ b/man/systemd-cryptsetup@.service.xml
@@ -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
index 0000000000..072f55f1a1
--- /dev/null
+++ b/man/systemd-delta.xml
@@ -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
index 0000000000..762b6ab992
--- /dev/null
+++ b/man/systemd-detect-virt.xml
@@ -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
index 0000000000..62f63110e1
--- /dev/null
+++ b/man/systemd-fsck@.service.xml
@@ -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
index 0000000000..2decec6c40
--- /dev/null
+++ b/man/systemd-fstab-generator.xml
@@ -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>luks.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
index 0000000000..1c9c9345f9
--- /dev/null
+++ b/man/systemd-getty-generator.xml
@@ -0,0 +1,90 @@
+<?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>
+ </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
index 0000000000..6a6bfdc7d7
--- /dev/null
+++ b/man/systemd-halt.service.xml
@@ -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
index 0000000000..d9c1911018
--- /dev/null
+++ b/man/systemd-hostnamed.service.xml
@@ -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
index 0000000000..6f63c8c73e
--- /dev/null
+++ b/man/systemd-inhibit.xml
@@ -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
index 0000000000..eda6459b50
--- /dev/null
+++ b/man/systemd-initctl.service.xml
@@ -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-journald.service.xml b/man/systemd-journald.service.xml
new file mode 100644
index 0000000000..abc03df5db
--- /dev/null
+++ b/man/systemd-journald.service.xml
@@ -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
index 0000000000..6cefc4265f
--- /dev/null
+++ b/man/systemd-localed.service.xml
@@ -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
index 0000000000..00f34051a3
--- /dev/null
+++ b/man/systemd-logind.service.xml
@@ -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
index 0000000000..25fb63af2d
--- /dev/null
+++ b/man/systemd-machine-id-setup.xml
@@ -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
index 0000000000..e5f10a7beb
--- /dev/null
+++ b/man/systemd-modules-load.service.xml
@@ -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
index 0000000000..b03492c5c1
--- /dev/null
+++ b/man/systemd-notify.xml
@@ -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
index 0000000000..fef5c2c83a
--- /dev/null
+++ b/man/systemd-nspawn.xml
@@ -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
index 0000000000..4d0218b659
--- /dev/null
+++ b/man/systemd-quotacheck.service.xml
@@ -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
index 0000000000..87f563e293
--- /dev/null
+++ b/man/systemd-random-seed-load.service.xml
@@ -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
index 0000000000..66d253454b
--- /dev/null
+++ b/man/systemd-readahead-replay.service.xml
@@ -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
index 0000000000..d920c0c400
--- /dev/null
+++ b/man/systemd-remount-fs.service.xml
@@ -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
index 0000000000..c1b8ef7a49
--- /dev/null
+++ b/man/systemd-shutdownd.service.xml
@@ -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
index 0000000000..9b8bad4791
--- /dev/null
+++ b/man/systemd-suspend.service.xml
@@ -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
index 0000000000..72a102c128
--- /dev/null
+++ b/man/systemd-sysctl.service.xml
@@ -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
index 0000000000..18a23ed7fc
--- /dev/null
+++ b/man/systemd-system-update-generator.xml
@@ -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
index 0000000000..ea2abc5765
--- /dev/null
+++ b/man/systemd-timedated.service.xml
@@ -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
index 0000000000..22744c7c41
--- /dev/null
+++ b/man/systemd-tmpfiles.xml
@@ -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
index 0000000000..31a18ba4b0
--- /dev/null
+++ b/man/systemd-tty-ask-password-agent.xml
@@ -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
index 0000000000..92fb38f067
--- /dev/null
+++ b/man/systemd-udevd.service.xml
@@ -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
index 0000000000..0e19581f98
--- /dev/null
+++ b/man/systemd-update-utmp-runlevel.service.xml
@@ -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
index 0000000000..9214ec9c35
--- /dev/null
+++ b/man/systemd-user-sessions.service.xml
@@ -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
index 0000000000..c1ef80dae4
--- /dev/null
+++ b/man/systemd-vconsole-setup.service.xml
@@ -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
index 0000000000..fe559e1dcb
--- /dev/null
+++ b/man/systemd.automount.xml
@@ -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
index 0000000000..a6be932c73
--- /dev/null
+++ b/man/systemd.conf.xml
@@ -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
index 0000000000..141d72e3dc
--- /dev/null
+++ b/man/systemd.device.xml
@@ -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
index 0000000000..7b6514375d
--- /dev/null
+++ b/man/systemd.exec.xml
@@ -0,0 +1,1154 @@
+<?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. Takes an integer between 1
+ (lowest priority) and 99 (highest
+ priority). The available priority
+ range depends on the selected CPU
+ scheduling policy (see above). 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, 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>1</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
index 0000000000..76a436d650
--- /dev/null
+++ b/man/systemd.journal-fields.xml
@@ -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
index 0000000000..3fff2f57e6
--- /dev/null
+++ b/man/systemd.kill.xml
@@ -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
index 0000000000..219ef6531e
--- /dev/null
+++ b/man/systemd.mount.xml
@@ -0,0 +1,282 @@
+<?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.</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
index 0000000000..a27a97be77
--- /dev/null
+++ b/man/systemd.path.xml
@@ -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
index 0000000000..a692053876
--- /dev/null
+++ b/man/systemd.preset.xml
@@ -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
index 0000000000..00a6398a1e
--- /dev/null
+++ b/man/systemd.service.xml
@@ -0,0 +1,924 @@
+<?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>Takes a command line
+ that is executed when this service
+ shall be started up. The first token
+ of the command line must be an
+ absolute file name, then followed by
+ arguments for the process. It is
+ mandatory to set this option for all
+ services. This option may not be
+ specified more than once, except when
+ <varname>Type=oneshot</varname> is
+ used in which case more than one
+ <varname>ExecStart=</varname> line is
+ accepted which are then invoked one by
+ one, sequentially in the order they
+ appear in the unit file.</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
+ first token 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 for the
+ same command the former must precede
+ the latter. Unless
+ <varname>Type=forking</varname> is
+ set, the process started via this
+ command line will be considered the
+ main process of the daemon. The
+ command line accepts % specifiers as
+ described in
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</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. Multiple
+ command lines may be concatenated in a
+ single directive, by separating them
+ by semicolons (these semicolons must
+ be passed as separate words). In that
+ case, the commands are executed one
+ after the other,
+ serially. Alternatively, these
+ directives 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.
+ Use of these settings is
+ optional. Specifier and environment
+ variable substitution is
+ supported.</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 pointed out for
+ <varname>ExecStartPre=</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 pointed
+ out for
+ <varname>ExecStartPre=</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 pointed
+ out for
+ <varname>ExecStartPre</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
index 0000000000..b432682a48
--- /dev/null
+++ b/man/systemd.snapshot.xml
@@ -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
index 0000000000..4b1fcc8b0c
--- /dev/null
+++ b/man/systemd.socket.xml
@@ -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
index 0000000000..9ea288e337
--- /dev/null
+++ b/man/systemd.special.xml
@@ -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
index 0000000000..a932143d43
--- /dev/null
+++ b/man/systemd.swap.xml
@@ -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
index 0000000000..d1f4d22674
--- /dev/null
+++ b/man/systemd.target.xml
@@ -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.timer.xml b/man/systemd.timer.xml
new file mode 100644
index 0000000000..6fc26a5536
--- /dev/null
+++ b/man/systemd.timer.xml
@@ -0,0 +1,192 @@
+<?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 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></listitem>
+
+ <para>These are monotonic timers,
+ independent of wall-clock time and timezones. If the
+ computer is temporarily suspended, the
+ monotonic clock stops too.</para>
+
+ </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>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
new file mode 100644
index 0000000000..c20efe5527
--- /dev/null
+++ b/man/systemd.unit.xml
@@ -0,0 +1,1084 @@
+<?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.</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>%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>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>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>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd.xml b/man/systemd.xml
new file mode 100644
index 0000000000..7b3d265b8d
--- /dev/null
+++ b/man/systemd.xml
@@ -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
index 0000000000..4c6064f54a
--- /dev/null
+++ b/man/telinit.xml
@@ -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
index 0000000000..01ca0a73d5
--- /dev/null
+++ b/man/timedatectl.xml
@@ -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
index 0000000000..785264e3cf
--- /dev/null
+++ b/man/tmpfiles.d.xml
@@ -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
index 0000000000..7ec7a3fed0
--- /dev/null
+++ b/man/udev.xml
@@ -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
index 0000000000..015980a63b
--- /dev/null
+++ b/man/udevadm.xml
@@ -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 /etc/udev/hwdb.bin.</para>
+ <variablelist>
+ <varlistentry>
+ <term><option>--update</option></term>
+ <listitem>
+ <para>Compile the hardware dabase information located in /usr/lib/udev/hwdb.d/,
+ /etc/udev/hwdb.d/ and store it in /etc/udev/hwdb.bin. This should be done with
+ 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
index 0000000000..45156b7447
--- /dev/null
+++ b/man/vconsole.conf.xml
@@ -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
index 0000000000..1fa8d3fd56
--- /dev/null
+++ b/po/.gitignore
@@ -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
index 0000000000..2829c87f1c
--- /dev/null
+++ b/po/POTFILES.in
@@ -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
index 0000000000..0502c13023
--- /dev/null
+++ b/po/POTFILES.skip
@@ -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
index 0000000000..2581d01fcc
--- /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
index 0000000000..93a50ddd80
--- /dev/null
+++ b/rules/.gitignore
@@ -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
index 0000000000..c9f67c7a24
--- /dev/null
+++ b/rules/42-usb-hid-pm.rules
@@ -0,0 +1,45 @@
+#
+# 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"
+
+# AMI 046b:ff10
+ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="046b", ATTR{idProduct}=="ff10", 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
index 0000000000..fc52fd17f5
--- /dev/null
+++ b/rules/50-udev-default.rules
@@ -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
index 0000000000..6eaf76a72c
--- /dev/null
+++ b/rules/60-cdrom_id.rules
@@ -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
index 0000000000..8154e2dbb5
--- /dev/null
+++ b/rules/60-persistent-alsa.rules
@@ -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
index 0000000000..0e33e68384
--- /dev/null
+++ b/rules/60-persistent-input.rules
@@ -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
index 0000000000..2948200c53
--- /dev/null
+++ b/rules/60-persistent-serial.rules
@@ -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
index 0000000000..f2eabd92a8
--- /dev/null
+++ b/rules/60-persistent-storage-tape.rules
@@ -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
index 0000000000..b74821edd4
--- /dev/null
+++ b/rules/60-persistent-storage.rules
@@ -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
index 0000000000..93c5ee8c27
--- /dev/null
+++ b/rules/60-persistent-v4l.rules
@@ -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
index 0000000000..a6a2bfd088
--- /dev/null
+++ b/rules/61-accelerometer.rules
@@ -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
index 0000000000..fe0100131e
--- /dev/null
+++ b/rules/64-btrfs.rules
@@ -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
index 0000000000..fe9fca14db
--- /dev/null
+++ b/rules/75-net-description.rules
@@ -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
index 0000000000..c0e0839785
--- /dev/null
+++ b/rules/75-probe_mtd.rules
@@ -0,0 +1,8 @@
+# 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"
+KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", IMPORT{builtin}="kmod load sm_ftl"
+
+LABEL="mtd_probe_end"
diff --git a/rules/75-tty-description.rules b/rules/75-tty-description.rules
new file mode 100644
index 0000000000..83083d93ea
--- /dev/null
+++ b/rules/75-tty-description.rules
@@ -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
index 0000000000..295f490150
--- /dev/null
+++ b/rules/78-sound-card.rules
@@ -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
index 0000000000..692510c912
--- /dev/null
+++ b/rules/80-drivers.rules
@@ -0,0 +1,12 @@
+# 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"
+
+LABEL="drivers_end"
diff --git a/rules/95-udev-late.rules b/rules/95-udev-late.rules
new file mode 100644
index 0000000000..eca0faa5c5
--- /dev/null
+++ b/rules/95-udev-late.rules
@@ -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
index 0000000000..d17bdd9a0a
--- /dev/null
+++ b/rules/99-systemd.rules.in
@@ -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
index 0000000000..4c8161ff2b
--- /dev/null
+++ b/shell-completion/systemd-bash-completion.sh
@@ -0,0 +1,605 @@
+# 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-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 kexec list-jobs list-units
+ list-unit-files poweroff reboot rescue show-environment'
+ [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 -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'
+ [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 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
index 0000000000..59755e62d9
--- /dev/null
+++ b/shell-completion/systemd-zsh-completion.zsh
@@ -0,0 +1,1023 @@
+#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' \
+ {-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]'
+ ;;
+ 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 is possible, otherwise start or restart"
+ "force-reload:Reload one or more units is possible, otherwise restart if active"
+ "reload-or-try-restart:Reload one or more units is 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"
+ "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-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
index 0000000000..afabb6a5d2
--- /dev/null
+++ b/src/.gitignore
@@ -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
index 0000000000..9d07505194
--- /dev/null
+++ b/src/Makefile
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/ac-power/Makefile
@@ -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
index 0000000000..37313cf144
--- /dev/null
+++ b/src/ac-power/ac-power.c
@@ -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 <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <libudev.h>
+
+#include "util.h"
+
+static int on_ac_power(void) {
+ int r;
+
+ struct udev *udev;
+ struct udev_enumerate *e = NULL;
+ struct udev_list_entry *item = NULL, *first = NULL;
+ bool found_offline = false, found_online = false;
+
+ 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, "power_supply") < 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) {
+ struct udev_device *d;
+ const char *type, *online;
+
+ if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!(type = udev_device_get_sysattr_value(d, "type")))
+ goto next;
+
+ if (!streq(type, "Mains"))
+ goto next;
+
+ if (!(online = udev_device_get_sysattr_value(d, "online")))
+ goto next;
+
+ if (streq(online, "1")) {
+ found_online = true;
+ break;
+ } else if (streq(online, "0"))
+ found_offline = true;
+
+ next:
+ udev_device_unref(d);
+ }
+
+ r = found_online || !found_offline;
+
+finish:
+ if (e)
+ udev_enumerate_unref(e);
+
+ if (udev)
+ udev_unref(udev);
+
+ return r;
+}
+
+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. */
+
+ if ((r = on_ac_power()) < 0) {
+ log_error("Failed to read AC status: %s", strerror(-r));
+ return EXIT_FAILURE;
+ }
+
+ return r == 0;
+}
diff --git a/src/analyze/Makefile b/src/analyze/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/analyze/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/analyze/systemd-analyze b/src/analyze/systemd-analyze
new file mode 100755
index 0000000000..88699d6728
--- /dev/null
+++ b/src/analyze/systemd-analyze
@@ -0,0 +1,294 @@
+#!/usr/bin/python
+
+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)
+
+ 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.stderr.write("Bootup is not yet finished. Please try again later.\n")
+ sys.exit(1)
+
+ assert initrd_time <= userspace_time
+ assert userspace_time <= finish_time
+
+ return 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():
+
+ initrd_time, start_time, finish_time = acquire_start_time()
+
+ if initrd_time > 0:
+ sys.stdout.write("Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums\n" % ( \
+ initrd_time/1000, \
+ (start_time - initrd_time)/1000, \
+ (finish_time - start_time)/1000, \
+ finish_time/1000))
+ else:
+ sys.stdout.write("Startup finished in %lums (kernel) + %lums (userspace) = %lums\n" % ( \
+ start_time/1000, \
+ (finish_time - start_time)/1000, \
+ finish_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.stderr.write("Failed to initilize python-cairo required for 'plot' verb.\n")
+ sys.exit(1)
+ initrd_time, start_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 >= start_time and ixt <= finish_time) or \
+ (aet >= start_time and aet <= finish_time) or \
+ (axt >= start_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, start_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, start_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, start_time/10000, y, finish_time/10000-start_time/10000, bar_height, 0.7, 0.7, 0.7)
+ draw_text(context, start_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 >= start_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 >= start_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 >= start_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, \
+ (start_time - initrd_time)/1000, \
+ (finish_time - start_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" % ( \
+ start_time/1000, \
+ (finish_time - start_time)/1000, \
+ finish_time/1000), hcenter = 0, vcenter = -1)
+
+ surface.finish()
+
+parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/ask-password/Makefile
@@ -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
index 0000000000..5f675700f8
--- /dev/null
+++ b/src/ask-password/ask-password.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/binfmt/Makefile
@@ -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
index 0000000000..788fd4b1a4
--- /dev/null
+++ b/src/binfmt/binfmt.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/cgls/Makefile
@@ -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
index 0000000000..b2cd968e46
--- /dev/null
+++ b/src/cgls/cgls.c
@@ -0,0 +1,182 @@
+/*-*- 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(DISTRIBUTION);
+ 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 *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 *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);
+ free(root);
+ }
+
+ free(p);
+ }
+
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/cgroups-agent/Makefile
@@ -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
index 0000000000..7a6173e2a2
--- /dev/null
+++ b/src/cgroups-agent/cgroups-agent.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/cgtop/Makefile
@@ -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
index 0000000000..f2e62761f1
--- /dev/null
+++ b/src/cgtop/cgtop.c
@@ -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
index 0000000000..a763f72507
--- /dev/null
+++ b/src/core/.gitignore
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/core/Makefile
@@ -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
index 0000000000..5955bd846e
--- /dev/null
+++ b/src/core/audit-fd.c
@@ -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
index 0000000000..8b58289dc5
--- /dev/null
+++ b/src/core/audit-fd.h
@@ -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
index 0000000000..b1619a64e6
--- /dev/null
+++ b/src/core/automount.c
@@ -0,0 +1,902 @@
+/*-*- 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 "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"
+
+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;
+
+ if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 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])
+ if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 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("Cannot have an automount unit for the root directory. Refusing.");
+ return -EINVAL;
+ }
+
+ if (!(e = unit_name_from_path(a->where, ".automount")))
+ return -ENOMEM;
+
+ b = unit_has_name(UNIT(a), e);
+ free(e);
+
+ if (!b) {
+ log_error("%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 */
+ if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
+ return r;
+
+ if (u->load_state == UNIT_LOADED) {
+ Unit *x;
+
+ if (!a->where)
+ if (!(a->where = unit_name_to_path(u->id)))
+ return -ENOMEM;
+
+ path_kill_slashes(a->where);
+
+ if ((r = automount_add_mount_links(a)) < 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)
+ if ((r = automount_add_default_dependencies(a)) < 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("%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) {
+
+ if ((r = open_dev_autofs(u->manager)) < 0)
+ return r;
+
+ if (a->deserialized_state == AUTOMOUNT_WAITING ||
+ a->deserialized_state == AUTOMOUNT_RUNNING) {
+
+ assert(a->pipe_fd >= 0);
+
+ if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 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);
+
+ if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 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;
+ int r;
+
+ assert(dev_autofs_fd >= 0);
+ assert(where);
+
+ l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
+
+ if (!(param = malloc(l)))
+ return -ENOMEM;
+
+ 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) {
+ r = -errno;
+ goto finish;
+ }
+
+ if (param->ioctlfd < 0) {
+ r = -EIO;
+ goto finish;
+ }
+
+ fd_cloexec(param->ioctlfd, true);
+ r = param->ioctlfd;
+
+finish:
+ free(param);
+ return r;
+}
+
+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;
+
+ if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) {
+ r = ioctl_fd;
+ goto fail;
+ }
+
+ if (status)
+ log_debug("Sending failure: %s", strerror(-status));
+ else
+ log_debug("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! */
+
+ if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
+ ioctl_fd,
+ token,
+ status)) < 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);
+
+ if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) {
+ r = dev_autofs_fd;
+ goto fail;
+ }
+
+ /* We knowingly ignore the results of this call */
+ mkdir_p_label(a->where, 0555);
+
+ if (dir_is_empty(a->where) <= 0)
+ log_notice("%s: Directory %s to mount over is not empty, mounting anyway. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", 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;
+ }
+
+ if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
+ r = ioctl_fd;
+ goto fail;
+ }
+
+ if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
+ goto fail;
+
+ if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 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;
+
+ if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 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("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;
+ 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("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("%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("%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("%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);
+ dbus_error_free(&error);
+}
+
+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("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;
+
+ if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 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;
+
+ if ((state = automount_state_from_string(value)) < 0)
+ log_debug("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("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("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("Failed to parse token value %s", value);
+ else {
+ if (!a->tokens)
+ if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
+ return -ENOMEM;
+
+ if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 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("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("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("Got invalid poll event on pipe.");
+ goto fail;
+ }
+
+ if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
+ log_error("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) {
+ char *p = NULL;
+
+ get_process_comm(packet.v5_packet.pid, &p);
+ log_debug("Got direct mount request on %s, triggered by %lu (%s)",
+ a->where, (unsigned long) packet.v5_packet.pid, strna(p));
+ free(p);
+
+ } else
+ log_debug("Got direct mount request on %s", a->where);
+
+ if (!a->tokens)
+ if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
+ log_error("Failed to allocate token set.");
+ goto fail;
+ }
+
+ if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) {
+ log_error("Failed to remember token: %s", strerror(-r));
+ goto fail;
+ }
+
+ automount_enter_runnning(a);
+ break;
+
+ default:
+ log_error("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
index 0000000000..3d5736d1cb
--- /dev/null
+++ b/src/core/automount.h
@@ -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
index 0000000000..4513a0bad7
--- /dev/null
+++ b/src/core/build.h
@@ -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
index 0000000000..04c1b2849d
--- /dev/null
+++ b/src/core/bus-errors.h
@@ -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
index 0000000000..71af09cf87
--- /dev/null
+++ b/src/core/cgroup-attr.c
@@ -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
index 0000000000..2b754eac40
--- /dev/null
+++ b/src/core/cgroup-attr.h
@@ -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
index 0000000000..8fc1731485
--- /dev/null
+++ b/src/core/cgroup.c
@@ -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
index 0000000000..229da52ba4
--- /dev/null
+++ b/src/core/cgroup.h
@@ -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
index 0000000000..32a37ccad6
--- /dev/null
+++ b/src/core/condition.c
@@ -0,0 +1,370 @@
+/*-*- 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;
+}
+
+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_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_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
index 0000000000..03954e40b3
--- /dev/null
+++ b/src/core/condition.h
@@ -0,0 +1,69 @@
+/*-*- 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_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
index 0000000000..060cbf7707
--- /dev/null
+++ b/src/core/dbus-automount.c
@@ -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
index 0000000000..b338e25fc1
--- /dev/null
+++ b/src/core/dbus-automount.h
@@ -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
index 0000000000..dbd91fe3db
--- /dev/null
+++ b/src/core/dbus-device.c
@@ -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
index 0000000000..311e0685d1
--- /dev/null
+++ b/src/core/dbus-device.h
@@ -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
index 0000000000..e815cb58e4
--- /dev/null
+++ b/src/core/dbus-execute.c
@@ -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
index 0000000000..eaa1b73e69
--- /dev/null
+++ b/src/core/dbus-execute.h
@@ -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
index 0000000000..fdc1dce177
--- /dev/null
+++ b/src/core/dbus-job.c
@@ -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
index 0000000000..a1b928fb16
--- /dev/null
+++ b/src/core/dbus-job.h
@@ -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
index 0000000000..165f63074b
--- /dev/null
+++ b/src/core/dbus-kill.c
@@ -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
index 0000000000..238fbd36d6
--- /dev/null
+++ b/src/core/dbus-kill.h
@@ -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
index 0000000000..2010241e6a
--- /dev/null
+++ b/src/core/dbus-manager.c
@@ -0,0 +1,1685 @@
+/*-*- 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=\"Distribution\" 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"
+ DISTRIBUTION "\0"
+ SYSTEMD_FEATURES;
+
+static const BusProperty bus_systemd_properties[] = {
+ { "Version", bus_property_append_string, "s", 0 },
+ { "Distribution", bus_property_append_string, "s", sizeof(PACKAGE_STRING) },
+ { "Features", bus_property_append_string, "s", sizeof(PACKAGE_STRING) + sizeof(DISTRIBUTION) },
+ { 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);
+
+ if (!(reply = dbus_message_new_method_return(message)))
+ 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;
+
+ if (!(reply = dbus_message_new_method_return(message))) {
+ 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;
+
+ if (!(reply = dbus_message_new_method_return(message))) {
+ 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);
+ dbus_message_unref(reply);
+ 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
index 0000000000..f0dce5a2e9
--- /dev/null
+++ b/src/core/dbus-manager.h
@@ -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
index 0000000000..d81edeb807
--- /dev/null
+++ b/src/core/dbus-mount.c
@@ -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
index 0000000000..8597394373
--- /dev/null
+++ b/src/core/dbus-mount.h
@@ -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
index 0000000000..f7fed1754d
--- /dev/null
+++ b/src/core/dbus-path.c
@@ -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
index 0000000000..c945f7d588
--- /dev/null
+++ b/src/core/dbus-path.h
@@ -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
index 0000000000..d99058dd46
--- /dev/null
+++ b/src/core/dbus-service.c
@@ -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
index 0000000000..143aed7ae5
--- /dev/null
+++ b/src/core/dbus-service.h
@@ -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
index 0000000000..435c6df39c
--- /dev/null
+++ b/src/core/dbus-snapshot.c
@@ -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
index 0000000000..1208aafff6
--- /dev/null
+++ b/src/core/dbus-snapshot.h
@@ -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
index 0000000000..095a031612
--- /dev/null
+++ b/src/core/dbus-socket.c
@@ -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
index 0000000000..5369b22e5e
--- /dev/null
+++ b/src/core/dbus-socket.h
@@ -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
index 0000000000..67ea0f24fe
--- /dev/null
+++ b/src/core/dbus-swap.c
@@ -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
index 0000000000..41fe4447ff
--- /dev/null
+++ b/src/core/dbus-swap.h
@@ -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
index 0000000000..6a775506cc
--- /dev/null
+++ b/src/core/dbus-target.c
@@ -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
index 0000000000..a8a0304c75
--- /dev/null
+++ b/src/core/dbus-target.h
@@ -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
index 0000000000..84b823c9a4
--- /dev/null
+++ b/src/core/dbus-timer.c
@@ -0,0 +1,140 @@
+/*-*- 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);
+ if (!(buf = new(char, l+2)))
+ 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) },
+ { "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
index 0000000000..9ac30501d1
--- /dev/null
+++ b/src/core/dbus-timer.h
@@ -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
index 0000000000..83ee018ff3
--- /dev/null
+++ b/src/core/dbus-unit.c
@@ -0,0 +1,887 @@
+/*-*- 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;
+ char *p;
+
+ assert(i);
+ assert(property);
+ assert(u);
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
+ return -ENOMEM;
+
+ if (u->job) {
+
+ if (!(p = job_dbus_path(u->job)))
+ 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)) {
+ free(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. */
+
+ if (!(p = unit_dbus_path(u)))
+ return -ENOMEM;
+
+ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &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 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);
+
+ if ((cgb = unit_get_default_cgroup(u))) {
+ if (!(t = cgroup_bonding_to_string(cgb)))
+ 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 *t;
+ bool success;
+
+ if (!(t = cgroup_bonding_to_string(cgb)))
+ return -ENOMEM;
+
+ success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t);
+ free(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 *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);
+
+ free(v);
+
+ 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) {
+ char *p = NULL;
+ 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;
+ }
+
+ if (!(p = unit_dbus_path(u)))
+ 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) {
+
+ if (!(m = bus_properties_changed_new(p,
+ UNIT_VTABLE(u)->bus_interface,
+ UNIT_VTABLE(u)->bus_invalidating_properties)))
+ goto oom;
+
+ if (bus_broadcast(u->manager, m) < 0)
+ goto oom;
+
+ dbus_message_unref(m);
+ }
+
+ if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", INVALIDATING_PROPERTIES)))
+ goto oom;
+
+ } else {
+ /* Send a new signal */
+
+ if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitNew")))
+ 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;
+
+ free(p);
+ dbus_message_unref(m);
+
+ u->sent_dbus_new_signal = true;
+
+ return;
+
+oom:
+ free(p);
+
+ if (m)
+ dbus_message_unref(m);
+
+ log_error("Failed to allocate unit change/new signal.");
+}
+
+void bus_unit_send_removed_signal(Unit *u) {
+ char *p = NULL;
+ 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;
+
+ if (!(p = unit_dbus_path(u)))
+ goto oom;
+
+ if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitRemoved")))
+ 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;
+
+ free(p);
+ dbus_message_unref(m);
+
+ return;
+
+oom:
+ free(p);
+
+ if (m)
+ dbus_message_unref(m);
+
+ log_error("Failed to allocate unit remove signal.");
+}
+
+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
index 0000000000..ac6785a949
--- /dev/null
+++ b/src/core/dbus-unit.h
@@ -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
index 0000000000..2a1c66054a
--- /dev/null
+++ b/src/core/dbus.c
@@ -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
index 0000000000..c7a058e198
--- /dev/null
+++ b/src/core/dbus.h
@@ -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
index 0000000000..be76cafaed
--- /dev/null
+++ b/src/core/device.c
@@ -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("%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
index 0000000000..3c4604f60e
--- /dev/null
+++ b/src/core/device.h
@@ -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
index 0000000000..e236d38e0f
--- /dev/null
+++ b/src/core/execute.c
@@ -0,0 +1,2132 @@
+/*-*- 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>
+
+#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 "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"
+#include "sd-id128.h"
+#include "sd-messages.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;
+
+ fn = *i;
+
+ if (fn[0] == '-') {
+ ignore = true;
+ fn ++;
+ }
+
+ if (!path_is_absolute(fn)) {
+
+ if (ignore)
+ continue;
+
+ strv_free(r);
+ return -EINVAL;
+ }
+
+ if ((k = load_env_file(fn, &p)) < 0) {
+
+ if (ignore)
+ continue;
+
+ strv_free(r);
+ 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)
+ return -ENOMEM;
+
+ r = m;
+ }
+ }
+
+ *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
index 0000000000..2bcd2e1e6c
--- /dev/null
+++ b/src/core/execute.h
@@ -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/fdset.c b/src/core/fdset.c
new file mode 100644
index 0000000000..fe918cd8cc
--- /dev/null
+++ b/src/core/fdset.c
@@ -0,0 +1,167 @@
+/*-*- 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"
+
+#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);
+
+ if ((copy = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
+ return -errno;
+
+ if ((r = fdset_put(s, copy)) < 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 fdsets and fills in all currently open file
+ * descriptors. */
+
+ if (!(d = opendir("/proc/self/fd")))
+ return -errno;
+
+ if (!(s = fdset_new())) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ while ((de = readdir(d))) {
+ int fd = -1;
+
+ if (ignore_file(de->d_name))
+ continue;
+
+ if ((r = safe_atoi(de->d_name, &fd)) < 0)
+ goto finish;
+
+ if (fd < 3)
+ continue;
+
+ if (fd == dirfd(d))
+ continue;
+
+ if ((r = fdset_put(s, fd)) < 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;
+}
diff --git a/src/core/fdset.h b/src/core/fdset.h
new file mode 100644
index 0000000000..c3e408c8ad
--- /dev/null
+++ b/src/core/fdset.h
@@ -0,0 +1,37 @@
+/*-*- 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 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_cloexec(FDSet *fds, bool b);
diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
new file mode 100644
index 0000000000..dbd2227e21
--- /dev/null
+++ b/src/core/hostname-setup.c
@@ -0,0 +1,182 @@
+/*-*- 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"
+
+#if defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+#define FILENAME "/etc/sysconfig/network"
+#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE)
+#define FILENAME "/etc/HOSTNAME"
+#elif defined(TARGET_GENTOO)
+#define FILENAME "/etc/conf.d/hostname"
+#endif
+
+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;
+}
+
+static int read_distro_hostname(char **hn) {
+
+#if defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+ int r;
+ _cleanup_fclose_ FILE *f = NULL;
+
+ assert(hn);
+
+ f = fopen(FILENAME, "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ char line[LINE_MAX];
+ char *s, *k;
+
+ if (!fgets(line, sizeof(line), f)) {
+ if (feof(f))
+ break;
+
+ r = -errno;
+ goto finish;
+ }
+
+ s = strstrip(line);
+
+ if (!startswith_no_case(s, "HOSTNAME="))
+ continue;
+
+ k = strdup(s+9);
+ if (!k) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ hostname_cleanup(k);
+
+ if (isempty(k)) {
+ free(k);
+ r = -ENOENT;
+ goto finish;
+ }
+
+ *hn = k;
+ r = 0;
+ goto finish;
+ }
+
+ r = -ENOENT;
+
+finish:
+ return r;
+
+#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE)
+ return read_and_strip_hostname(FILENAME, hn);
+#else
+ return -ENOENT;
+#endif
+}
+
+static int read_hostname(char **hn) {
+ int r;
+
+ assert(hn);
+
+ /* First, try to load the generic hostname configuration file,
+ * that we support on all distributions */
+
+ r = read_and_strip_hostname("/etc/hostname", hn);
+ if (r < 0) {
+ if (r == -ENOENT)
+ return read_distro_hostname(hn);
+
+ return r;
+ }
+
+ return 0;
+}
+
+int hostname_setup(void) {
+ int r;
+ char *b = NULL;
+ const char *hn = NULL;
+ bool enoent = false;
+
+ r = read_hostname(&b);
+ if (r < 0) {
+ hn = NULL;
+
+ if (r == -ENOENT)
+ enoent = true;
+ else
+ log_warning("Failed to read configured hostname: %s", strerror(-r));
+ } else
+ hn = b;
+
+ if (isempty(hn)) {
+ /* Don't override the hostname if it is already set
+ * and not explicitly configured */
+ if (hostname_is_set())
+ goto finish;
+
+ 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);
+ r = -errno;
+ } else
+ log_info("Set hostname to <%s>.", hn);
+
+finish:
+ free(b);
+
+ return r;
+}
diff --git a/src/core/hostname-setup.h b/src/core/hostname-setup.h
new file mode 100644
index 0000000000..8dc3a9e1d8
--- /dev/null
+++ b/src/core/hostname-setup.h
@@ -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
index 0000000000..e8cc1ba8b6
--- /dev/null
+++ b/src/core/ima-setup.c
@@ -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
index 0000000000..14b56d1fc2
--- /dev/null
+++ b/src/core/ima-setup.h
@@ -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
index 0000000000..859042ce42
--- /dev/null
+++ b/src/core/initreq.h
@@ -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
index 0000000000..f08b8cbc7d
--- /dev/null
+++ b/src/core/job.c
@@ -0,0 +1,1086 @@
+/*-*- 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("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("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("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 %s already has a job installed. Not installing deserialized job.", j->unit->id);
+ return -EEXIST;
+ }
+ *pj = j;
+ j->installed = true;
+ log_debug("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("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("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 tread 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_notice("Job %s/%s failed with result '%s'.",
+ u->id,
+ job_type_to_string(t),
+ job_result_to_string(result));
+
+ 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("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
index 0000000000..3aa49d4b46
--- /dev/null
+++ b/src/core/job.h
@@ -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
index 0000000000..0775653f73
--- /dev/null
+++ b/src/core/kill.c
@@ -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
index 0000000000..3c9b0ab8db
--- /dev/null
+++ b/src/core/kill.h
@@ -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
index 0000000000..55200ffa48
--- /dev/null
+++ b/src/core/killall.c
@@ -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
index 0000000000..d08ac142f0
--- /dev/null
+++ b/src/core/killall.h
@@ -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
index 0000000000..20ab232374
--- /dev/null
+++ b/src/core/kmod-setup.c
@@ -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
index 0000000000..24dcdddfa4
--- /dev/null
+++ b/src/core/kmod-setup.h
@@ -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
index 0000000000..86f81c7484
--- /dev/null
+++ b/src/core/load-dropin.c
@@ -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
index 0000000000..1d2fafeee6
--- /dev/null
+++ b/src/core/load-dropin.h
@@ -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
index 0000000000..0c5ccebd73
--- /dev/null
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -0,0 +1,255 @@
+%{
+#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.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.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.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
index 0000000000..5803044178
--- /dev/null
+++ b/src/core/load-fragment.c
@@ -0,0 +1,2541 @@
+/*-*- 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 <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 *t, *k;
+ int r;
+
+ t = strndup(w, l);
+ if (!t)
+ return -ENOMEM;
+
+ k = unit_name_printf(u, t);
+ free(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));
+
+ free(k);
+ }
+
+ 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 (;;) {
+ 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;
+
+ if (rvalue[0] == '-') {
+ ignore = true;
+ rvalue ++;
+ }
+
+ if (rvalue[0] == '@') {
+ honour_argv0 = true;
+ rvalue ++;
+ }
+
+ if (*rvalue != '/') {
+ log_error("[%s:%u] Invalid executable path in command line, 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;
+
+ 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;
+ 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;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* On Linux RR/FIFO have the same range */
+ if (safe_atoi(rvalue, &i) < 0 || i < sched_get_priority_min(SCHED_RR) || i > sched_get_priority_max(SCHED_RR)) {
+ log_error("[%s:%u] Failed to parse CPU scheduling priority, 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 *t;
+ int r;
+ unsigned cpu;
+
+ if (!(t = strndup(w, l)))
+ return -ENOMEM;
+
+ r = safe_atou(t, &cpu);
+ free(t);
+
+ if (!(c->cpuset))
+ if (!(c->cpuset = cpu_set_malloc(&c->cpuset_ncpus)))
+ return -ENOMEM;
+
+ if (r < 0 || cpu >= c->cpuset_ncpus) {
+ log_error("[%s:%u] Failed to parse CPU affinity, ignoring: %s", filename, line, 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 *t;
+ int r;
+ cap_value_t cap;
+
+ t = strndup(w, l);
+ if (!t)
+ return -ENOMEM;
+
+ r = cap_from_name(t, &cap);
+ free(t);
+
+ if (r < 0) {
+ log_error("[%s:%u] Failed to parse capability bounding set, ignoring: %s", filename, line, rvalue);
+ 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 *t, *k;
+ int r;
+
+ t = strndup(w, l);
+ if (!t)
+ return -ENOMEM;
+
+ k = unit_full_printf(u, t);
+ free(t);
+
+ if (!k)
+ return -ENOMEM;
+
+ t = cunescape(k);
+ free(k);
+
+ if (!t)
+ return -ENOMEM;
+
+ r = unit_add_cgroup_from_text(u, t);
+ free(t);
+
+ if (r < 0) {
+ log_error("[%s:%u] Failed to parse cgroup value, ignoring: %s", filename, line, 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_QUOTED(w, l, rvalue, state) {
+ if (strncmp(w, "shared", MAX(l, 6U)) == 0)
+ flags |= MS_SHARED;
+ else if (strncmp(w, "slave", MAX(l, 5U)) == 0)
+ flags |= MS_SLAVE;
+ else if (strncmp(w, "private", MAX(l, 7U)) == 0)
+ flags |= MS_PRIVATE;
+ else {
+ log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, 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;
+ TimerValue *v;
+ TimerBase b;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if ((b = timer_base_from_string(lvalue)) < 0) {
+ log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue);
+ return 0;
+ }
+
+ if (parse_usec(rvalue, &u) < 0) {
+ log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if (!(v = new0(TimerValue, 1)))
+ return -ENOMEM;
+
+ v->base = b;
+ v->value = u;
+
+ 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 *t, *k;
+
+ t = strndup(w, l);
+ if (!t)
+ return -ENOMEM;
+
+ k = unit_name_printf(UNIT(s), t);
+ free(t);
+
+ if (!k)
+ return -ENOMEM;
+
+ if (!endswith(k, ".socket")) {
+ log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue);
+ free(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;
+
+ free(k);
+ }
+
+ 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 *t;
+
+ t = strndup(w, l);
+ if (!t)
+ return -ENOMEM;
+
+ id = syscall_from_name(t);
+ free(t);
+
+ if (id < 0) {
+ log_error("[%s:%u] Failed to parse syscall, ignoring: %s", filename, line, rvalue);
+ 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
index 0000000000..24f738464c
--- /dev/null
+++ b/src/core/load-fragment.h
@@ -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
index 0000000000..b9bd3a0748
--- /dev/null
+++ b/src/core/locale-setup.c
@@ -0,0 +1,241 @@
+/*-*- 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)
+ if ((r = parse_env_file("/proc/cmdline", WHITESPACE,
+#if defined(TARGET_FEDORA)
+ "LANG", &variables[VARIABLE_LANG],
+#endif
+ "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)) < 0) {
+
+ if (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)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
+ }
+
+#if defined(TARGET_ALTLINUX)
+ if (r <= 0 &&
+ (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
+ "LANG", &variables[VARIABLE_LANG],
+ NULL)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+ }
+
+#elif defined(TARGET_SUSE)
+ if (r <= 0 &&
+ (r = parse_env_file("/etc/sysconfig/language", NEWLINE,
+ "RC_LANG", &variables[VARIABLE_LANG],
+ NULL)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/language: %s", strerror(-r));
+ }
+
+#elif defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ if (r <= 0 &&
+ (r = parse_env_file("/etc/default/locale", NEWLINE,
+ "LANG", &variables[VARIABLE_LANG],
+ "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)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/default/locale: %s", strerror(-r));
+ }
+
+#elif defined(TARGET_GENTOO)
+ /* Gentoo's openrc expects locale variables in /etc/env.d/
+ * These files are later compiled by env-update into shell
+ * export commands at /etc/profile.env, with variables being
+ * exported by openrc's runscript (so /etc/init.d/)
+ */
+ if (r <= 0 &&
+ (r = parse_env_file("/etc/profile.env", NEWLINE,
+ "export LANG", &variables[VARIABLE_LANG],
+ "export LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
+ "export LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
+ "export LC_TIME", &variables[VARIABLE_LC_TIME],
+ "export LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
+ "export LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
+ "export LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
+ "export LC_PAPER", &variables[VARIABLE_LC_PAPER],
+ "export LC_NAME", &variables[VARIABLE_LC_NAME],
+ "export LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
+ "export LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
+ "export LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
+ "export LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
+ NULL)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/profile.env: %s", strerror(-r));
+ }
+#elif defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA )
+ if (r <= 0 &&
+ (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
+ "LANG", &variables[VARIABLE_LANG],
+ "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)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+ }
+
+#endif
+
+ if (!variables[VARIABLE_LANG]) {
+ if (!(variables[VARIABLE_LANG] = strdup("C"))) {
+ 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
index 0000000000..5a0f2f7888
--- /dev/null
+++ b/src/core/locale-setup.h
@@ -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
index 0000000000..065b75a6e3
--- /dev/null
+++ b/src/core/loopback-setup.c
@@ -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
index 0000000000..dd83cf13a7
--- /dev/null
+++ b/src/core/loopback-setup.h
@@ -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
index 0000000000..7f4c23b130
--- /dev/null
+++ b/src/core/machine-id-setup.c
@@ -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
index 0000000000..b9e6b4d674
--- /dev/null
+++ b/src/core/machine-id-setup.h
@@ -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
index 0000000000..e521df337d
--- /dev/null
+++ b/src/core/macros.systemd.in
@@ -0,0 +1,56 @@
+# -*- 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@
+
+%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}
diff --git a/src/core/main.c b/src/core/main.c
new file mode 100644
index 0000000000..4da8ecb864
--- /dev/null
+++ b/src/core/main.c
@@ -0,0 +1,1950 @@
+/*-*- 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"
+#include "kmod-setup.h"
+#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;
+
+ if ((r = safe_atoi(optarg, &fd)) < 0 || fd < 0) {
+ log_error("Failed to parse deserialize option %s.", optarg);
+ return r;
+ }
+
+ if (!(f = fdopen(fd, "r"))) {
+ log_error("Failed to open serialization fd: %m");
+ return r;
+ }
+
+ 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(DISTRIBUTION);
+ 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 */
+ if (serialization) {
+ r = fdset_new_fill(&fds);
+ if (r < 0) {
+ log_error("Failed to allocate fd set: %s", strerror(-r));
+ goto finish;
+ }
+
+ assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
+ } else
+ close_all_fds(NULL, 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");
+
+ /* 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 "; " DISTRIBUTION ")");
+
+ 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 "; " DISTRIBUTION ")");
+
+ if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
+ locale_setup();
+
+ if (arg_show_status || plymouth_running())
+ status_welcome();
+
+ kmod_setup();
+ 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. */
+ if (fds) {
+ fdset_free(fds);
+ fds = NULL;
+ }
+
+ 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
index 0000000000..f932c79a1b
--- /dev/null
+++ b/src/core/manager.c
@@ -0,0 +1,2309 @@
+/*-*- 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>
+
+#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)
+ return -errno;
+
+ sa.un.sun_path[0] = '@';
+ m->notify_socket = strdup(sa.un.sun_path);
+ if (!m->notify_socket)
+ return -ENOMEM;
+
+ log_debug("Using notification socket %s", m->notify_socket);
+
+ 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;
+ if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 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;
+
+ m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.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;
+
+ if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
+ goto fail;
+
+ if ((r = manager_setup_signals(m)) < 0)
+ goto fail;
+
+ if ((r = manager_setup_cgroup(m)) < 0)
+ goto fail;
+
+ if ((r = manager_setup_notify(m)) < 0)
+ goto fail;
+
+ /* Try to connect to the busses, if possible. */
+ if ((r = bus_init(m, running_as != SYSTEMD_SYSTEM)) < 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("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);
+
+ 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;
+
+ if (!(d = opendir(*i))) {
+ 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;
+ }
+
+ /* 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("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("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);
+
+ if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 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);
+
+ if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid))))
+ if (!(u = cgroup_unit_by_pid(m, ucred->pid))) {
+ 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;
+ if (!(tags = strv_split(buf, "\n\r")))
+ return -ENOMEM;
+
+ log_debug("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 *name = NULL;
+
+ get_process_comm(si.si_pid, &name);
+ log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
+ free(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. */
+ if ((r = manager_process_notify_fd(m)) < 0)
+ return r;
+
+ /* And now figure out the unit this belongs to */
+ if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid))))
+ 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("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("Activating special unit %s", name);
+
+ if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0)
+ log_error("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 (;;) {
+ if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != 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 */
+ if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) {
+
+ if (k < 0 && (errno == EINTR || errno == EAGAIN))
+ break;
+
+ 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;
+
+ 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;
+
+ if ((r = safe_atou(s + 30, &id)) < 0)
+ return r;
+
+ if (!(j = manager_get_job(m, id)))
+ 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;
+
+ if (!(p = unit_name_to_prefix_and_instance(u->id))) {
+ log_error("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);
+
+ if (!(f = fdopen(fd, "w+")))
+ 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);
+
+ if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0)
+ goto finish;
+
+ if ((r = unit_deserialize(u, f, fds)) < 0)
+ goto finish;
+ }
+
+finish:
+ if (ferror(f)) {
+ r = -EIO;
+ goto finish;
+ }
+
+ assert(m->n_reloading > 0);
+ m->n_reloading --;
+
+ return r;
+}
+
+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 */
+ if (!(u = manager_get_unit(m, name)))
+ 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();
+}
diff --git a/src/core/manager.h b/src/core/manager.h
new file mode 100644
index 0000000000..22145024f1
--- /dev/null
+++ b/src/core/manager.h
@@ -0,0 +1,293 @@
+/*-*- 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
+};
+
+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;
+
+ 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_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);
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
new file mode 100644
index 0000000000..98614d0c3e
--- /dev/null
+++ b/src/core/mount-setup.c
@@ -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
index 0000000000..4b521ad0e1
--- /dev/null
+++ b/src/core/mount-setup.h
@@ -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
index 0000000000..14f4863dc6
--- /dev/null
+++ b/src/core/mount.c
@@ -0,0 +1,1885 @@
+/*-*- 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 "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])
+ if ((r = swap_add_one_mount_link(SWAP(other), m)) < 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])
+ if ((r = path_add_one_mount_link(PATH(other), m)) < 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])
+ if ((r = automount_add_one_mount_link(AUTOMOUNT(other), m)) < 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])
+ if ((r = socket_add_one_mount_link(SOCKET(other), m)) < 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("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("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("%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("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("%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("%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("%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;
+
+ if ((r = unit_watch_pid(UNIT(m), m->control_pid)) < 0)
+ return r;
+
+ if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 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);
+
+ if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 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("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("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 ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 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("%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);
+}
+
+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("%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);
+
+ if (dir_is_empty(m->where) <= 0)
+ log_notice("%s: Directory %s to mount over is not empty, mounting anyway. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", 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("%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("%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("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("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("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("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("Failed to parse exec-command value %s", value);
+ else {
+ m->control_command_id = id;
+ m->control_command = m->exec_command + id;
+ }
+
+ } else
+ log_debug("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(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+ "%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("%s mounting timed out. Stopping.", u->id);
+ mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
+ break;
+
+ case MOUNT_REMOUNTING:
+ log_warning("%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("%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("%s mounting timed out. Killing.", u->id);
+ mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%s remounting timed out. Killing.", u->id);
+ mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%s unmounting timed out. Killing.", u->id);
+ mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%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 */
+
+ if ((r = mount_load_proc_self_mountinfo(m, true)) < 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
index 0000000000..67d6132a5d
--- /dev/null
+++ b/src/core/mount.h
@@ -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
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ 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);
diff --git a/src/core/namespace.c b/src/core/namespace.c
new file mode 100644
index 0000000000..ba18ddc5b0
--- /dev/null
+++ b/src/core/namespace.c
@@ -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
index 0000000000..5d72ed91fb
--- /dev/null
+++ b/src/core/namespace.h
@@ -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
index 0000000000..a07a8e1ce3
--- /dev/null
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -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
index 0000000000..51bdafac45
--- /dev/null
+++ b/src/core/org.freedesktop.systemd1.policy.in.in
@@ -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
index 0000000000..d4df3e93a2
--- /dev/null
+++ b/src/core/org.freedesktop.systemd1.service
@@ -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
index 0000000000..3936971b41
--- /dev/null
+++ b/src/core/path.c
@@ -0,0 +1,773 @@
+/*-*- 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);
+
+ if (!(buf = malloc(l))) {
+ log_error("Failed to allocate buffer: %m");
+ r = -errno;
+ goto out;
+ }
+
+ if ((k = read(s->inotify_fd, buf, l)) < 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;
+
+ if ((r = mkdir_p_label(s->path, mode)) < 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("%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
index 0000000000..77926888ae
--- /dev/null
+++ b/src/core/path.h
@@ -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
index 0000000000..ba0bba5353
--- /dev/null
+++ b/src/core/securebits.h
@@ -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
index 0000000000..6dfe8b45f3
--- /dev/null
+++ b/src/core/selinux-access.c
@@ -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
index 0000000000..9183cbc9a6
--- /dev/null
+++ b/src/core/selinux-access.h
@@ -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
index 0000000000..e9c0de92f1
--- /dev/null
+++ b/src/core/selinux-setup.c
@@ -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
index 0000000000..39e2bc25bb
--- /dev/null
+++ b/src/core/selinux-setup.h
@@ -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
index 0000000000..cf08485374
--- /dev/null
+++ b/src/core/service.c
@@ -0,0 +1,3941 @@
+/*-*- 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,
+ RUNLEVEL_SYSINIT
+} 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 },
+
+#ifdef TARGET_SUSE
+ /* SUSE style boot.d */
+ { "boot.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT },
+#endif
+
+#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ /* Debian style rcS.d */
+ { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT },
+#endif
+
+ /* 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/SYSINIT must be read before DOWN */
+};
+
+#define RUNLEVELS_UP "12345"
+/* #define RUNLEVELS_DOWN "06" */
+#define RUNLEVELS_BOOT "bBsS"
+#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;
+
+ s->watchdog_watch.type = WATCH_INVALID;
+
+ s->timer_watch.type = WATCH_INVALID;
+#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("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("%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("%s watchdog timeout!", UNIT(s)->id);
+ service_enter_dead(s, SERVICE_FAILURE_WATCHDOG, true);
+ return;
+ }
+
+ r = unit_watch_timer(UNIT(s), s->watchdog_usec - offset, &s->watchdog_watch);
+ if (r < 0)
+ log_warning("%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 defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ if (endswith(name, ".sh"))
+ /* Drop Debian-style .sh suffix */
+ strcpy(stpcpy(r, name) - 3, ".service");
+#endif
+#ifdef TARGET_SUSE
+ if (startswith(name, "boot."))
+ /* Drop SuSE-style boot. prefix */
+ strcpy(stpcpy(r, name + 5), ".service");
+#endif
+#ifdef TARGET_FRUGALWARE
+ if (startswith(name, "rc."))
+ /* Drop Frugalware-style rc. prefix */
+ strcpy(stpcpy(r, name + 3), ".service");
+#endif
+ 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,
+#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+#else
+ /* 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,
+#endif
+ "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,
+
+#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ "mail-transport-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+#endif
+
+#ifdef TARGET_SUSE
+ "smtp", SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+#endif
+ };
+
+ 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("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("[%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("[%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("[%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("[%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("[%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("[%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_BOOT, s->sysv_runlevels) &&
+ chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
+ /* Service has both boot and "up" runlevels
+ configured. Kill the "up" ones. */
+ delete_chars(s->sysv_runlevels, RUNLEVELS_UP);
+ }
+
+ 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 boot.*, rc.* and *.sh
+ * prefixes/suffixes. */
+#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ if (endswith(name, ".sh.service"))
+ return -ENOENT;
+#endif
+
+#ifdef TARGET_SUSE
+ if (startswith(name, "boot."))
+ return -ENOENT;
+#endif
+
+#ifdef TARGET_FRUGALWARE
+ if (startswith(name, "rc."))
+ return -ENOENT;
+#endif
+
+ 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 defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM)
+ 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);
+ }
+#endif
+ free(path);
+
+#ifdef TARGET_SUSE
+ if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) {
+ /* Try SUSE style boot.* init scripts */
+
+ path = strjoin(*p, "/boot.", name, NULL);
+ if (!path)
+ return -ENOMEM;
+
+ /* Drop .service suffix */
+ path[strlen(path)-8] = 0;
+ r = service_load_sysv_path(s, path);
+ free(path);
+ }
+#endif
+
+#ifdef TARGET_FRUGALWARE
+ 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);
+ }
+#endif
+
+ 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("%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("%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("%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("%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("%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("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("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("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("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("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_struct(LOG_DEBUG,
+ "UNIT=%s", UNIT(s)->id,
+ "MESSAGE=%s changed %s -> %s", UNIT(s)->id,
+ service_state_to_string(old_state),
+ service_state_to_string(state),
+ NULL);
+
+ 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;
+
+ if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 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), 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), 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("%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("%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("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("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("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), 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("%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("%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("%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("%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("%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("Stop job pending for unit, delaying automatic restart.");
+
+ r = unit_watch_timer(UNIT(s), 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("%s scheduled restart job.", UNIT(s)->id);
+ return;
+
+fail:
+ log_warning("%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("%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("%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("%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("%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("%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("Failed to reboot: %s.", bus_error(&error, r));
+ dbus_error_free(&error);
+ }
+
+ break;
+ }
+
+ case SERVICE_START_LIMIT_REBOOT_FORCE:
+ log_warning("%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("%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
+ reboot(RB_AUTOBOOT);
+ break;
+
+ default:
+ log_error("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("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("%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(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+ "%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("%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("%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("%s operation timed out. Terminating.", u->id);
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
+ break;
+
+ case SERVICE_START_POST:
+ log_warning("%s operation timed out. Stopping.", u->id);
+ service_enter_stop(s, SERVICE_FAILURE_TIMEOUT);
+ break;
+
+ case SERVICE_RELOAD:
+ log_warning("%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("%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("%s stopping timed out. Killing.", u->id);
+ service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%s still around after SIGKILL. Ignoring.", u->id);
+ service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT);
+ break;
+
+ case SERVICE_STOP_POST:
+ log_warning("%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("%s stopping timed out (2). Killing.", u->id);
+ service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%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("%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("%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("%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("%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("%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("%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("Failed to parse notification message %s", e);
+ else {
+ log_debug("%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("%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("Status message in notification is not UTF-8 clean.");
+ return;
+ }
+
+ t = strdup(e+7);
+ if (!t) {
+ log_error("Failed to allocate string.");
+ return;
+ }
+
+ log_debug("%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("%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
+
+#ifdef TARGET_SUSE
+static void sysv_facility_in_insserv_conf(Manager *mgr) {
+ FILE *f=NULL;
+ int r;
+
+ if (!(f = fopen("/etc/insserv.conf", "re"))) {
+ r = errno == ENOENT ? 0 : -errno;
+ goto finish;
+ }
+
+ while (!feof(f)) {
+ char l[LINE_MAX], *t;
+ char **parsed = NULL;
+
+ if (!fgets(l, sizeof(l), f)) {
+ if (feof(f))
+ break;
+
+ r = -errno;
+ log_error("Failed to read configuration file '/etc/insserv.conf': %s", strerror(-r));
+ goto finish;
+ }
+
+ t = strstrip(l);
+ if (*t != '$' && *t != '<')
+ continue;
+
+ parsed = strv_split(t,WHITESPACE);
+ /* we ignore <interactive>, not used, equivalent to X-Interactive */
+ if (parsed && !startswith_no_case (parsed[0], "<interactive>")) {
+ char *facility;
+ Unit *u;
+ if (sysv_translate_facility(parsed[0], NULL, &facility) < 0)
+ continue;
+ if ((u = manager_get_unit(mgr, facility)) && (u->type == UNIT_TARGET)) {
+ UnitDependency e;
+ char *dep = NULL, *name, **j;
+
+ STRV_FOREACH (j, parsed+1) {
+ if (*j[0]=='+') {
+ e = UNIT_WANTS;
+ name = *j+1;
+ }
+ else {
+ e = UNIT_REQUIRES;
+ name = *j;
+ }
+ if (sysv_translate_facility(name, NULL, &dep) < 0)
+ continue;
+
+ r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, e, dep, NULL, true);
+ free(dep);
+ }
+ }
+ free(facility);
+ }
+ strv_free(parsed);
+ }
+finish:
+ if (f)
+ fclose(f);
+
+}
+#endif
+
+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;
+ }
+
+ if ((r = manager_load_unit_prepare(m, name, NULL, NULL, &service)) < 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 || rcnd_table[i].type == RUNLEVEL_SYSINIT) {
+ 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 ||
+ rcnd_table[i].type == RUNLEVEL_SYSINIT)) {
+
+ 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. On SUSE the boot.d/ runlevel is
+ * also used for shutdown, so we add links for that too to the
+ * 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;
+
+#ifdef TARGET_SUSE
+ sysv_facility_in_insserv_conf (m);
+#endif
+
+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("%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("%s's D-Bus name %s no longer registered by %s", u->id, name, old_owner);
+ else
+ log_debug("%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("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("%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
index 0000000000..d1e53bf727
--- /dev/null
+++ b/src/core/service.h
@@ -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
index 0000000000..cc8c57bd2d
--- /dev/null
+++ b/src/core/shutdown.c
@@ -0,0 +1,316 @@
+/*-*- 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;
+ 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("Disabling swaps.");
+ r = swapoff_all(&changed);
+ if (r == 0)
+ need_swapoff = false;
+ else if (r > 0)
+ log_info("Not all swaps are turned off, %d left.", r);
+ else
+ log_error("Failed to turn off 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;
+ 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;
+ else if (r > 0)
+ log_warning("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 &&
+ 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");
+ }
+ }
+
+ 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
index 0000000000..5c2a319cb6
--- /dev/null
+++ b/src/core/snapshot.c
@@ -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
index 0000000000..9662d93164
--- /dev/null
+++ b/src/core/snapshot.h
@@ -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
index 0000000000..c0959815c1
--- /dev/null
+++ b/src/core/socket.c
@@ -0,0 +1,2289 @@
+/*-*- 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>
+#include <attr/xattr.h>
+
+#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("%s lacks Listen setting. Refusing.", UNIT(s)->id);
+ return -EINVAL;
+ }
+
+ if (s->accept && have_non_accept_socket(s)) {
+ log_error("%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("%s's MaxConnection setting too small. Refusing.", UNIT(s)->id);
+ return -EINVAL;
+ }
+
+ if (s->accept && UNIT_DEREF(s->service)) {
+ log_error("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("%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("SO_KEEPALIVE failed: %m");
+ }
+
+ if (s->broadcast) {
+ int one = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
+ log_warning("SO_BROADCAST failed: %m");
+ }
+
+ if (s->pass_cred) {
+ int one = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+ log_warning("SO_PASSCRED failed: %m");
+ }
+
+ if (s->pass_sec) {
+ int one = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
+ log_warning("SO_PASSSEC failed: %m");
+ }
+
+ if (s->priority >= 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
+ log_warning("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("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("SO_SNDBUF failed: %m");
+ }
+
+ if (s->mark >= 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
+ log_warning("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("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("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("TCP_CONGESTION failed: %m");
+
+ if (s->smack_ip_in)
+ if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0)
+ log_error("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("fsetxattr(\"security.SMACK64IPOUT\"): %m");
+}
+
+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("F_SETPIPE_SZ: %m");
+
+ if (s->smack)
+ if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0)
+ log_error("fsetxattr(\"security.SMACK64\"): %m");
+}
+
+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("%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;
+
+ if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
+ return r;
+
+ if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 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);
+
+ if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
+ goto fail;
+
+ if (!(argv = unit_full_printf_strv(UNIT(s), c->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("%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("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("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 ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 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("%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("%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("%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("%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("%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("%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("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("%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("Too many incoming connections (%u)", 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("%s failed to queue socket startup job: %s", UNIT(s)->id, 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("%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("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("Socket service %s already active, refusing.", UNIT(service)->id);
+ return -EBUSY;
+ }
+
+#ifdef HAVE_SYSV_COMPAT
+ if (service->is_sysv) {
+ log_error("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;
+
+ if ((r = socket_address_print(&p->address, &t)) < 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 {
+ 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;
+
+ if ((state = socket_state_from_string(value)) < 0)
+ log_debug("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("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("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("Failed to parse control-pid value %s", value);
+ else
+ s->control_pid = pid;
+ } else if (streq(key, "control-command")) {
+ SocketExecCommand id;
+
+ if ((id = socket_exec_command_from_string(value)) < 0)
+ log_debug("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("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("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, "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("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("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("Unknown serialization key '%s'", key);
+
+ 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("Incoming traffic on %s", u->id);
+
+ if (events != EPOLLIN) {
+
+ if (events & EPOLLHUP)
+ log_error("%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("%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("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(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+ "%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("%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("%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("%s starting timed out. Terminating.", u->id);
+ socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
+ break;
+
+ case SOCKET_START_POST:
+ log_warning("%s starting timed out. Stopping.", u->id);
+ socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
+ break;
+
+ case SOCKET_STOP_PRE:
+ log_warning("%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("%s stopping timed out. Killing.", u->id);
+ socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%s still around after SIGKILL. Ignoring.", u->id);
+ socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
+ break;
+
+ case SOCKET_STOP_POST:
+ log_warning("%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("%s stopping timed out (2). Killing.", u->id);
+ socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->id);
+ socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
+ }
+ break;
+
+ case SOCKET_FINAL_SIGKILL:
+ log_warning("%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("%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("%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,
+
+ .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
index 0000000000..f099520dce
--- /dev/null
+++ b/src/core/socket.h
@@ -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
index 0000000000..ef72260ecd
--- /dev/null
+++ b/src/core/special.h
@@ -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
index 0000000000..97145a9974
--- /dev/null
+++ b/src/core/swap.c
@@ -0,0 +1,1433 @@
+/*-*- 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("%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("%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("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("%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), 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), 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("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("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), 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("%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("%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("%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("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("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("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("Failed to parse exec-command value %s", value);
+ else {
+ s->control_command_id = id;
+ s->control_command = s->exec_command + id;
+ }
+
+ } else
+ log_debug("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(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+ "%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("%s activation timed out. Stopping.", u->id);
+ swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
+ break;
+
+ case SWAP_DEACTIVATING:
+ log_warning("%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("%s activation timed out. Killing.", u->id);
+ swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%s deactivation timed out. Killing.", u->id);
+ swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
+ } else {
+ log_warning("%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("%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
index 0000000000..35d47fd46f
--- /dev/null
+++ b/src/core/swap.h
@@ -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
index 0000000000..150332a858
--- /dev/null
+++ b/src/core/switch-root.c
@@ -0,0 +1,142 @@
+/*-*- 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"
+
+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;
+
+ if (path_equal(new_root, "/"))
+ return 0;
+
+ 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");
+ }
+
+ 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
index 0000000000..0c4cd1e403
--- /dev/null
+++ b/src/core/switch-root.h
@@ -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
index 0000000000..05fad3e158
--- /dev/null
+++ b/src/core/syscall-list.c
@@ -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
index 0000000000..0fc6859605
--- /dev/null
+++ b/src/core/syscall-list.h
@@ -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
index 0000000000..9ffd129c48
--- /dev/null
+++ b/src/core/sysfs-show.h
@@ -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
index 0000000000..68076d9735
--- /dev/null
+++ b/src/core/system.conf
@@ -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
index 0000000000..2f49d5df52
--- /dev/null
+++ b/src/core/systemd.pc.in
@@ -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
index 0000000000..981424132b
--- /dev/null
+++ b/src/core/target.c
@@ -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
index 0000000000..1676553add
--- /dev/null
+++ b/src/core/target.h
@@ -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
index 0000000000..6c630fac60
--- /dev/null
+++ b/src/core/tcpwrap.c
@@ -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
index 0000000000..3353b6596e
--- /dev/null
+++ b/src/core/tcpwrap.h
@@ -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
index 0000000000..7080b32c6b
--- /dev/null
+++ b/src/core/timer.c
@@ -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 "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 = (usec_t) -1;
+}
+
+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);
+ free(v);
+ }
+
+ unit_unwatch_timer(u, &t->timer_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("%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) {
+ if ((r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
+ return r;
+
+ if ((r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 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);
+
+ if ((r = unit_load_fragment_and_dropin(u)) < 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)
+ if ((r = timer_add_default_dependencies(t)) < 0)
+ return r;
+ }
+
+ return timer_verify(t);
+}
+
+static void timer_dump(Unit *u, FILE *f, const char *prefix) {
+ Timer *t = TIMER(u);
+ TimerValue *v;
+ char
+ timespan1[FORMAT_TIMESPAN_MAX];
+
+ 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)
+ 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->timer_watch);
+
+ if (state != old_state)
+ log_debug("%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, delay, n;
+ bool found = false;
+ int r;
+
+ n = now(CLOCK_MONOTONIC);
+
+ LIST_FOREACH(value, v, t->values) {
+
+ if (v->disabled)
+ continue;
+
+ switch (v->base) {
+
+ case TIMER_ACTIVE:
+ if (state_translation_table[t->state] == UNIT_ACTIVE)
+ base = UNIT(t)->inactive_exit_timestamp.monotonic;
+ else
+ base = n;
+ 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 < n) {
+ v->disabled = true;
+ continue;
+ }
+
+ if (!found)
+ t->next_elapse = v->next_elapse;
+ else
+ t->next_elapse = MIN(t->next_elapse, v->next_elapse);
+
+ found = true;
+ }
+
+ if (!found) {
+ timer_set_state(t, TIMER_ELAPSED);
+ return;
+ }
+
+ delay = n < t->next_elapse ? t->next_elapse - n : 0;
+
+ if ((r = unit_watch_timer(UNIT(t), delay, &t->timer_watch)) < 0)
+ goto fail;
+
+ timer_set_state(t, TIMER_WAITING);
+ return;
+
+fail:
+ log_warning("%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;
+
+ if ((r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL)) < 0)
+ goto fail;
+
+ timer_set_state(t, TIMER_RUNNING);
+ return;
+
+fail:
+ log_warning("%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;
+
+ if ((state = timer_state_from_string(value)) < 0)
+ log_debug("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("Failed to parse result value %s", value);
+ else if (f != TIMER_SUCCESS)
+ t->result = f;
+
+ } else
+ log_debug("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("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("%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 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"
+};
+
+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,
+
+ .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
index 0000000000..c6d1d42e44
--- /dev/null
+++ b/src/core/timer.h
@@ -0,0 +1,90 @@
+/*-*- 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"
+
+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_BASE_MAX,
+ _TIMER_BASE_INVALID = -1
+} TimerBase;
+
+typedef struct TimerValue {
+ usec_t value;
+ usec_t next_elapse;
+
+ LIST_FIELDS(struct TimerValue, value);
+
+ TimerBase base;
+ bool disabled;
+} 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;
+
+ TimerState state, deserialized_state;
+ UnitRef unit;
+
+ Watch timer_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
index 0000000000..4bce942012
--- /dev/null
+++ b/src/core/transaction.c
@@ -0,0 +1,1087 @@
+/*-*- 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("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("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("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("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)) {
+
+ log_info("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) {
+ log_warning("Breaking ordering cycle by deleting job %s/%s", delete->unit->id, job_type_to_string(delete->type));
+ 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("%s/%s would stop a running service.", j->unit->id, job_type_to_string(j->type));
+
+ if (changes_existing_job)
+ log_debug("%s/%s would change existing job.", j->unit->id, job_type_to_string(j->type));
+
+ /* Ok, let's get rid of this */
+ log_debug("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("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("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(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING,
+ "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(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING,
+ "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(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING,
+ "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("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("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("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
index 0000000000..67ace4da0b
--- /dev/null
+++ b/src/core/transaction.h
@@ -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
index 0000000000..83c9de3e82
--- /dev/null
+++ b/src/core/umount.c
@@ -0,0 +1,639 @@
+/*-*- 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 (path_equal(m->path, "/")
+#ifndef HAVE_SPLIT_USR
+ || path_equal(m->path, "/usr")
+#endif
+ ) {
+ n_failed++;
+ continue;
+ }
+
+ /* Trying to umount. Forcing to umount if busy (only for NFS mounts) */
+ if (umount2(m->path, MNT_FORCE) == 0) {
+ log_info("Unmounted %s.", m->path);
+ 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 mount_points_list_remount_read_only(MountPoint **head, bool *changed) {
+ MountPoint *m, *n;
+ int n_failed = 0;
+
+ assert(head);
+
+ LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+
+ /* Trying to remount read-only */
+ if (mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL) == 0) {
+ if (changed)
+ *changed = true;
+
+ mount_point_free(head, m);
+ } else {
+ log_warning("Could not remount as read-only %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) {
+ 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;
+ }
+
+ if ((r = delete_loopback(m->path)) >= 0) {
+
+ if (r > 0 && changed)
+ *changed = true;
+
+ mount_point_free(head, m);
+ } else {
+ log_warning("Could not delete 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;
+ }
+
+ if ((r = delete_dm(m->devnum)) >= 0) {
+
+ if (r > 0 && changed)
+ *changed = true;
+
+ mount_point_free(head, m);
+ } else {
+ log_warning("Could not delete 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;
+
+ /* 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)
+ r = mount_points_list_remount_read_only(&mp_list_head, changed);
+
+ 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
index 0000000000..8439ffe58f
--- /dev/null
+++ b/src/core/umount.h
@@ -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
index 0000000000..cbae45d9f7
--- /dev/null
+++ b/src/core/unit-printf.c
@@ -0,0 +1,346 @@
+/*-*- 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;
+
+ assert(u);
+
+ c = unit_get_exec_context(u);
+ if (!c)
+ return NULL;
+
+ /* get USER env from our own env if set */
+ if (!c->user)
+ return getusername_malloc();
+
+ /* fish username from passwd */
+ username = c->user;
+ r = get_user_creds(&username, NULL, NULL, NULL, NULL);
+ if (r < 0)
+ return NULL;
+
+ return strdup(username);
+}
+
+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);
+ if (!c)
+ return NULL;
+
+ /* return HOME if set, otherwise from passwd */
+ if (!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);
+ if (!c)
+ return NULL;
+
+ /* return HOME if set, otherwise from passwd */
+ if (!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 },
+ { '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
index 0000000000..d2f4ccd178
--- /dev/null
+++ b/src/core/unit-printf.h
@@ -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
index 0000000000..99e1c27948
--- /dev/null
+++ b/src/core/unit.c
@@ -0,0 +1,2738 @@
+/*-*- 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, usec_t delay, 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;
+ if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
+ return -errno;
+ } else
+ assert_not_reached("Invalid watch type");
+
+ zero(its);
+
+ if (delay <= 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, delay);
+ flags = 0;
+ }
+
+ /* 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
index 0000000000..bf961c2aac
--- /dev/null
+++ b/src/core/unit.h
@@ -0,0 +1,551 @@
+/*-*- 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);
+
+ /* 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);
+
+ /* 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, usec_t delay, 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);
diff --git a/src/core/user.conf b/src/core/user.conf
new file mode 100644
index 0000000000..e02b46bc3a
--- /dev/null
+++ b/src/core/user.conf
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/cryptsetup/Makefile
@@ -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
index 0000000000..386714b4fd
--- /dev/null
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -0,0 +1,449 @@
+/*-*- 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 = -ENOMEM;
+ log_error("Failed to allocate unit name.");
+ goto fail;
+ }
+
+ p = strjoin(arg_dest, "/", n, NULL);
+ if (!p) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit file name.");
+ goto fail;
+ }
+
+ u = fstab_node_to_udev_node(device);
+ if (!u) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device node.");
+ goto fail;
+ }
+
+ d = unit_name_from_path(u, ".device");
+ if (!d) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device name.");
+ goto fail;
+ }
+
+ f = fopen(p, "wxe");
+ if (!f) {
+ r = -errno;
+ log_error("Failed to create unit file: %m");
+ 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: %m");
+ goto fail;
+ }
+
+ if (asprintf(&from, "../%s", n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ if (!noauto) {
+
+ to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
+ if (!to) {
+ r = -ENOMEM;
+ 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 = -ENOMEM;
+ 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 = -ENOMEM;
+ 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 = -ENOMEM;
+ 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
index 0000000000..56a3b50974
--- /dev/null
+++ b/src/cryptsetup/cryptsetup.c
@@ -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"))
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/delta/Makefile
@@ -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
index 0000000000..a65cea51bc
--- /dev/null
+++ b/src/delta/delta.c
@@ -0,0 +1,490 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/detect-virt/Makefile
@@ -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
index 0000000000..bbb9dfc19a
--- /dev/null
+++ b/src/detect-virt/detect-virt.c
@@ -0,0 +1,172 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/fsck/Makefile
@@ -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
index 0000000000..058f34d64f
--- /dev/null
+++ b/src/fsck/fsck.c
@@ -0,0 +1,407 @@
+/*-*- 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.");
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+ else if (strneq(w, "fastboot", l))
+ arg_skip = true;
+ else if (strneq(w, "forcefsck", l))
+ arg_force = true;
+#endif
+ }
+
+ free(line);
+ return 0;
+}
+
+static void test_files(void) {
+ if (access("/fastboot", F_OK) >= 0)
+ arg_skip = true;
+
+ if (access("/forcefsck", F_OK) >= 0)
+ arg_force = true;
+
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/fstab-generator/Makefile
@@ -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
index 0000000000..62053b7f35
--- /dev/null
+++ b/src/fstab-generator/fstab-generator.c
@@ -0,0 +1,560 @@
+/*-*- 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 *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL;
+ FILE *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) {
+ r = log_oom();
+ goto finish;
+ }
+
+ unit = strjoin(arg_dest, "/", name, NULL);
+ if (!unit) {
+ r = log_oom();
+ goto finish;
+ }
+
+ f = fopen(unit, "wxe");
+ if (!f) {
+ r = -errno;
+ log_error("Failed to create unit file %s: %m", unit);
+ goto finish;
+ }
+
+ 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);
+ r = -errno;
+ goto finish;
+ }
+
+ if (!noauto) {
+ lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
+ if (!lnk) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mkdir_parents_label(lnk, 0755);
+ if (symlink(unit, lnk) < 0) {
+ log_error("Failed to create symlink %s: %m", lnk);
+ r = -errno;
+ goto finish;
+ }
+
+ r = device_name(what, &device);
+ if (r < 0)
+ goto finish;
+
+ if (r > 0) {
+ free(lnk);
+ lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL);
+ if (!lnk) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mkdir_parents_label(lnk, 0755);
+ if (symlink(unit, lnk) < 0) {
+ log_error("Failed to create symlink %s: %m", lnk);
+ r = -errno;
+ goto finish;
+ }
+ }
+ }
+
+ r = 0;
+finish:
+ if (f)
+ fclose(f);
+
+ free(unit);
+ free(lnk);
+ free(name);
+ free(device);
+
+ return r;
+}
+
+static bool mount_is_bind(struct mntent *me) {
+ assert(me);
+
+ return
+ hasmntopt(me, "bind") ||
+ streq(me->mnt_opts, "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, struct mntent *me) {
+ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, *automount_name = NULL, *automount_unit = NULL;
+ FILE *f = NULL;
+ bool noauto, nofail, automount, isbind, isnetwork;
+ int r;
+ const char *post, *pre;
+
+ assert(what);
+ assert(where);
+ assert(me);
+
+ if (streq(me->mnt_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;
+
+ isnetwork = mount_is_network(me);
+ isbind = mount_is_bind(me);
+
+ noauto = !!hasmntopt(me, "noauto");
+ nofail = !!hasmntopt(me, "nofail");
+ automount =
+ hasmntopt(me, "comment=systemd.automount") ||
+ hasmntopt(me, "x-systemd.automount");
+
+ 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) {
+ r = log_oom();
+ goto finish;
+ }
+
+ unit = strjoin(arg_dest, "/", name, NULL);
+ if (!unit) {
+ r = log_oom();
+ goto finish;
+ }
+
+ f = fopen(unit, "wxe");
+ if (!f) {
+ r = -errno;
+ log_error("Failed to create unit file %s: %m", unit);
+ goto finish;
+ }
+
+ fputs("# Automatically generated by systemd-fstab-generator\n\n"
+ "[Unit]\n"
+ "SourcePath=/etc/fstab\n"
+ "DefaultDependencies=no\n", f);
+
+ 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,
+ me->mnt_type,
+ me->mnt_passno);
+
+ if (!isempty(me->mnt_opts) &&
+ !streq(me->mnt_opts, "defaults"))
+ fprintf(f,
+ "Options=%s\n",
+ me->mnt_opts);
+
+ fflush(f);
+ if (ferror(f)) {
+ log_error("Failed to write unit file %s: %m", unit);
+ r = -errno;
+ goto finish;
+ }
+
+ if (!noauto) {
+ lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+ if (!lnk) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mkdir_parents_label(lnk, 0755);
+ if (symlink(unit, lnk) < 0) {
+ log_error("Failed to create symlink %s: %m", lnk);
+ r = -errno;
+ goto finish;
+ }
+
+ if (!isbind &&
+ !path_equal(where, "/")) {
+
+ r = device_name(what, &device);
+ if (r < 0)
+ goto finish;
+
+ if (r > 0) {
+ free(lnk);
+ lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL);
+ if (!lnk) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mkdir_parents_label(lnk, 0755);
+ if (symlink(unit, lnk) < 0) {
+ log_error("Failed to create symlink %s: %m", lnk);
+ r = -errno;
+ goto finish;
+ }
+ }
+ }
+ }
+
+ if (automount && !path_equal(where, "/")) {
+ automount_name = unit_name_from_path(where, ".automount");
+ if (!name) {
+ r = log_oom();
+ goto finish;
+ }
+
+ automount_unit = strjoin(arg_dest, "/", automount_name, NULL);
+ if (!automount_unit) {
+ r = log_oom();
+ goto finish;
+ }
+
+ fclose(f);
+ f = fopen(automount_unit, "wxe");
+ if (!f) {
+ r = -errno;
+ log_error("Failed to create unit file %s: %m", automount_unit);
+ goto finish;
+ }
+
+ 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);
+ r = -errno;
+ goto finish;
+ }
+
+ free(lnk);
+ lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
+ if (!lnk) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mkdir_parents_label(lnk, 0755);
+ if (symlink(automount_unit, lnk) < 0) {
+ log_error("Failed to create symlink %s: %m", lnk);
+ r = -errno;
+ goto finish;
+ }
+ }
+
+ r = 0;
+finish:
+ if (f)
+ fclose(f);
+
+ free(unit);
+ free(lnk);
+ free(name);
+ free(device);
+ free(automount_name);
+ free(automount_unit);
+
+ return r;
+}
+
+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 *where, *what;
+ int k;
+
+ what = fstab_node_to_udev_node(me->mnt_fsname);
+ if (!what) {
+ r = log_oom();
+ goto finish;
+ }
+
+ where = strdup(me->mnt_dir);
+ if (!where) {
+ r = log_oom();
+ free(what);
+ 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
+ k = add_mount(what, where, me);
+
+ free(what);
+ free(where);
+
+ if (k < 0)
+ r = k;
+ }
+
+finish:
+ endmntent(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, "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);
+ }
+
+ free(word);
+ }
+
+ r = 0;
+
+finish:
+ free(line);
+ return r;
+}
+
+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[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)
+ return EXIT_SUCCESS;
+
+ r = parse_fstab();
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/getty-generator/Makefile b/src/getty-generator/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/getty-generator/Makefile
@@ -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
index 0000000000..1cef6aeae9
--- /dev/null
+++ b/src/getty-generator/getty-generator.c
@@ -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 (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
index 0000000000..4577903c40
--- /dev/null
+++ b/src/gudev/.gitignore
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/gudev/Makefile
@@ -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
index 0000000000..5586fd6a61
--- /dev/null
+++ b/src/gudev/gjs-example.js
@@ -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
index 0000000000..058262d767
--- /dev/null
+++ b/src/gudev/gudev-1.0.pc.in
@@ -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
index 0000000000..6ae01f2bf1
--- /dev/null
+++ b/src/gudev/gudev.h
@@ -0,0 +1,33 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..2b94102ac5
--- /dev/null
+++ b/src/gudev/gudevclient.c
@@ -0,0 +1,527 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..b425d03d48
--- /dev/null
+++ b/src/gudev/gudevclient.h
@@ -0,0 +1,100 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..62a26f99b7
--- /dev/null
+++ b/src/gudev/gudevdevice.c
@@ -0,0 +1,963 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..d4873bad0f
--- /dev/null
+++ b/src/gudev/gudevdevice.h
@@ -0,0 +1,128 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..db09074625
--- /dev/null
+++ b/src/gudev/gudevenumerator.c
@@ -0,0 +1,431 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..3fddccf573
--- /dev/null
+++ b/src/gudev/gudevenumerator.h
@@ -0,0 +1,107 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..c3a0aa8747
--- /dev/null
+++ b/src/gudev/gudevenums.h
@@ -0,0 +1,49 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..fc30b39e2e
--- /dev/null
+++ b/src/gudev/gudevenumtypes.c.template
@@ -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
index 0000000000..d0ab3393e6
--- /dev/null
+++ b/src/gudev/gudevenumtypes.h.template
@@ -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
index 0000000000..7e665999e8
--- /dev/null
+++ b/src/gudev/gudevmarshal.list
@@ -0,0 +1 @@
+VOID:STRING,OBJECT
diff --git a/src/gudev/gudevprivate.h b/src/gudev/gudevprivate.h
new file mode 100644
index 0000000000..8866f52b88
--- /dev/null
+++ b/src/gudev/gudevprivate.h
@@ -0,0 +1,41 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..888482783d
--- /dev/null
+++ b/src/gudev/gudevtypes.h
@@ -0,0 +1,51 @@
+/* -*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..66206ad806
--- /dev/null
+++ b/src/gudev/seed-example-enum.js
@@ -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
index 0000000000..e2ac324d23
--- /dev/null
+++ b/src/gudev/seed-example.js
@@ -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
index 0000000000..1ff281b231
--- /dev/null
+++ b/src/hostname/.gitignore
@@ -0,0 +1 @@
+org.freedesktop.hostname1.policy
diff --git a/src/hostname/Makefile b/src/hostname/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/hostname/Makefile
@@ -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
index 0000000000..b7ae5ccc6c
--- /dev/null
+++ b/src/hostname/hostnamectl.c
@@ -0,0 +1,546 @@
+/*-*- 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;
+} 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",
+ strna(i->pretty_hostname),
+ strna(i->icon_name));
+
+ 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;
+ }
+ 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 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",
+ 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(DISTRIBUTION);
+ 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 '?':
+ 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 },
+ };
+
+ 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
index 0000000000..cd3ef491ac
--- /dev/null
+++ b/src/hostname/hostnamed.c
@@ -0,0 +1,636 @@
+/*-*- 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" \
+ " <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" \
+ " </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_MAX
+};
+
+static char *data[_PROP_MAX] = {
+ 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],
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ return r;
+
+ return 0;
+}
+
+static bool check_nss(void) {
+
+ void *dl;
+
+ if ((dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY))) {
+ dlclose(dl);
+ return true;
+ }
+
+ return false;
+}
+
+static const char* fallback_icon_name(void) {
+
+#if defined(__i386__) || defined(__x86_64__)
+ int r;
+ char *type;
+ unsigned t;
+#endif
+
+ if (detect_virtualization(NULL) > 0)
+ return "computer-vm";
+
+#if defined(__i386__) || defined(__x86_64__)
+ 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 "computer-desktop";
+
+ case 0x9:
+ case 0xA:
+ case 0xE:
+ return "computer-laptop";
+
+ case 0x11:
+ case 0x1C:
+ return "computer-server";
+ }
+
+#endif
+ return NULL;
+}
+
+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"
+ };
+
+ 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;
+
+ assert(i);
+ assert(property);
+
+ if (isempty(data[PROP_ICON_NAME]))
+ name = fallback_icon_name();
+ else
+ name = data[PROP_ICON_NAME];
+
+ 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 },
+ { 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")) {
+
+ 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 : 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);
+
+ 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" : "icon name", strempty(data[k]));
+
+ changed = bus_properties_changed_new(
+ "/org/freedesktop/hostname1",
+ "org.freedesktop.hostname1",
+ k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" : "IconName\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 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
index 0000000000..46b4aadc83
--- /dev/null
+++ b/src/hostname/org.freedesktop.hostname1.conf
@@ -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
index 0000000000..df082d8e6f
--- /dev/null
+++ b/src/hostname/org.freedesktop.hostname1.policy.in
@@ -0,0 +1,49 @@
+<?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>
+ </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
index 0000000000..6041ed60ca
--- /dev/null
+++ b/src/hostname/org.freedesktop.hostname1.service
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/initctl/Makefile
@@ -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
index 0000000000..0eb008d9e6
--- /dev/null
+++ b/src/initctl/initctl.c
@@ -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
index 0000000000..d6a79460cd
--- /dev/null
+++ b/src/journal/.gitignore
@@ -0,0 +1,2 @@
+/journald-gperf.c
+/libsystemd-journal.pc
diff --git a/src/journal/Makefile b/src/journal/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/journal/Makefile
@@ -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
index 0000000000..3594f70c87
--- /dev/null
+++ b/src/journal/browse.html
@@ -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
index 0000000000..523a7a2eda
--- /dev/null
+++ b/src/journal/cat.c
@@ -0,0 +1,180 @@
+/*-*- 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(DISTRIBUTION);
+ 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/compress.c b/src/journal/compress.c
new file mode 100644
index 0000000000..75e70c5ffa
--- /dev/null
+++ b/src/journal/compress.c
@@ -0,0 +1,208 @@
+/*-*- 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 "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) {
+
+ lzma_stream s = LZMA_STREAM_INIT;
+ lzma_ret ret;
+ 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;
+ s.avail_out = *dst_alloc_size;
+
+ for (;;) {
+ void *p;
+
+ ret = lzma_code(&s, LZMA_FINISH);
+
+ if (ret == LZMA_STREAM_END)
+ break;
+
+ if (ret != LZMA_OK)
+ goto fail;
+
+ p = realloc(*dst, *dst_alloc_size*2);
+ if (!p)
+ goto fail;
+
+ s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst);
+ s.avail_out += *dst_alloc_size;
+
+ *dst = p;
+ *dst_alloc_size *= 2;
+ }
+
+ *dst_size = *dst_alloc_size - 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
index 0000000000..b6f1aa0ed7
--- /dev/null
+++ b/src/journal/compress.h
@@ -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);
+
+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
index 0000000000..a507fc65f8
--- /dev/null
+++ b/src/journal/coredump.c
@@ -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
index 0000000000..4adc9236f1
--- /dev/null
+++ b/src/journal/coredumpctl.c
@@ -0,0 +1,583 @@
+/*-*- 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(DISTRIBUTION);
+ 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);
+
+ 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);
+
+ 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);
+
+ 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
index 0000000000..2190b7c796
--- /dev/null
+++ b/src/journal/fsprg.c
@@ -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
index 0000000000..306ef18d73
--- /dev/null
+++ b/src/journal/fsprg.h
@@ -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
index 0000000000..64bf96874e
--- /dev/null
+++ b/src/journal/journal-authenticate.c
@@ -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
index 0000000000..0aaf836721
--- /dev/null
+++ b/src/journal/journal-authenticate.h
@@ -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
index 0000000000..ac5611c310
--- /dev/null
+++ b/src/journal/journal-def.h
@@ -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
+};
+
+_packed_ 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[];
+};
+
+#define TAG_LENGTH (256/8)
+
+_packed_ struct TagObject {
+ ObjectHeader object;
+ le64_t seqnum;
+ le64_t epoch;
+ uint8_t tag[TAG_LENGTH]; /* SHA-256 HMAC */
+};
+
+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' })
+
+_packed_ 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 */
+};
+
+#define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })
+
+_packed_ 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;
+};
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
new file mode 100644
index 0000000000..3df099dbd2
--- /dev/null
+++ b/src/journal/journal-file.c
@@ -0,0 +1,2872 @@
+/*-*- 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))
+ 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))
+ 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
index 0000000000..cdbc8e41f6
--- /dev/null
+++ b/src/journal/journal-file.h
@@ -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
index 0000000000..35462795c2
--- /dev/null
+++ b/src/journal/journal-gatewayd.c
@@ -0,0 +1,916 @@
+/*-*- 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 *t;
+
+ t = strndup(colon + 1, colon2 - colon - 1);
+ if (!t)
+ return -ENOMEM;
+
+ r = safe_atoi64(t, &m->n_skip);
+ free(t);
+ 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
index 0000000000..75a4129e5b
--- /dev/null
+++ b/src/journal/journal-internal.h
@@ -0,0 +1,127 @@
+/*-*- 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;
+};
+
+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
index 0000000000..10a14e4def
--- /dev/null
+++ b/src/journal/journal-qrcode.c
@@ -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
index 0000000000..da6244c160
--- /dev/null
+++ b/src/journal/journal-qrcode.h
@@ -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
index 0000000000..8589d94479
--- /dev/null
+++ b/src/journal/journal-send.c
@@ -0,0 +1,608 @@
+/*-*- 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)
+
+/* 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";
+
+ if (_unlikely_(!iov))
+ return -EINVAL;
+
+ if (_unlikely_(n <= 0))
+ return -EINVAL;
+
+ saved_errno = errno;
+
+ w = alloca(sizeof(struct iovec) * n * 5);
+ 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;
+ }
+
+ 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");
+ }
+
+ 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;
+ size_t fl;
+
+ 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. */
+ fl = strlen(func) + 1;
+ f = alloca(fl + 10);
+ memcpy(f, "CODE_FUNC=", 10);
+ memcpy(f + 10, func, fl);
+
+ 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;
+ size_t fl;
+
+ va_start(ap, format);
+ i = fill_iovec_sprintf(format, ap, 3, &iov);
+ va_end(ap);
+
+ if (_unlikely_(i < 0)) {
+ r = i;
+ goto finish;
+ }
+
+ fl = strlen(func) + 1;
+ f = alloca(fl + 10);
+ memcpy(f, "CODE_FUNC=", 10);
+ memcpy(f + 10, func, fl);
+
+ 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;
+ size_t fl;
+
+ 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);
+
+ fl = strlen(func) + 1;
+ f = alloca(fl + 10);
+ memcpy(f, "CODE_FUNC=", 10);
+ memcpy(f + 10, func, fl);
+
+ 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];
+ size_t fl;
+ char *f;
+
+ fl = strlen(func) + 1;
+ f = alloca(fl + 10);
+ memcpy(f, "CODE_FUNC=", 10);
+ memcpy(f + 10, func, fl);
+
+ 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
index 0000000000..731f6c770f
--- /dev/null
+++ b/src/journal/journal-vacuum.c
@@ -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
index 0000000000..f5e3e5291f
--- /dev/null
+++ b/src/journal/journal-vacuum.h
@@ -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
index 0000000000..1a67d5a04b
--- /dev/null
+++ b/src/journal/journal-verify.c
@@ -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))
+ 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
index 0000000000..e392ab61d7
--- /dev/null
+++ b/src/journal/journal-verify.h
@@ -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
index 0000000000..cccd8a7692
--- /dev/null
+++ b/src/journal/journalctl.c
@@ -0,0 +1,1060 @@
+/*-*- 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"
+
+#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
+
+static OutputMode arg_output = OUTPUT_SHORT;
+static bool arg_follow = 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 enum {
+ ACTION_SHOW,
+ ACTION_NEW_ID128,
+ ACTION_PRINT_HEADER,
+ ACTION_SETUP_KEYS,
+ ACTION_VERIFY,
+ ACTION_DISK_USAGE,
+} 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"
+ " -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"
+#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_SETUP_KEYS,
+ ARG_INTERVAL,
+ ARG_VERIFY,
+ ARG_VERIFY_KEY,
+ ARG_DISK_USAGE,
+ ARG_SINCE,
+ ARG_UNTIL
+ };
+
+ 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' },
+ { "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", no_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' },
+ { 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:", options, NULL)) >= 0) {
+
+ switch (c) {
+
+ case 'h':
+ help();
+ return 0;
+
+ case ARG_VERSION:
+ puts(PACKAGE_STRING);
+ puts(DISTRIBUTION);
+ 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 '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;
+
+ 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;
+ }
+
+ 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 |
+ (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+ on_tty() * OUTPUT_COLOR;
+
+ 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
index 0000000000..be55f94878
--- /dev/null
+++ b/src/journal/journald-console.c
@@ -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
index 0000000000..aa8e6579ba
--- /dev/null
+++ b/src/journal/journald-console.h
@@ -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
index 0000000000..1baef1411c
--- /dev/null
+++ b/src/journal/journald-gperf.gperf
@@ -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
index 0000000000..b8198760d6
--- /dev/null
+++ b/src/journal/journald-kmsg.c
@@ -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
index 0000000000..f287161329
--- /dev/null
+++ b/src/journal/journald-kmsg.h
@@ -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
index 0000000000..ac3183ece3
--- /dev/null
+++ b/src/journal/journald-native.c
@@ -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->syslog_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
index 0000000000..16c09f523e
--- /dev/null
+++ b/src/journal/journald-native.h
@@ -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
index 0000000000..8bd68476a3
--- /dev/null
+++ b/src/journal/journald-rate-limit.c
@@ -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
index 0000000000..648ab22786
--- /dev/null
+++ b/src/journal/journald-rate-limit.h
@@ -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
index 0000000000..0ff2866c11
--- /dev/null
+++ b/src/journal/journald-server.c
@@ -0,0 +1,1502 @@
+/*-*- 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->path)
+ 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_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
index 0000000000..9f50a29e50
--- /dev/null
+++ b/src/journal/journald-server.h
@@ -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
index 0000000000..7b88f747db
--- /dev/null
+++ b/src/journal/journald-stream.c
@@ -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
index 0000000000..dfb6267bf6
--- /dev/null
+++ b/src/journal/journald-stream.h
@@ -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
index 0000000000..afddca3630
--- /dev/null
+++ b/src/journal/journald-syslog.c
@@ -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
index 0000000000..7ff215b524
--- /dev/null
+++ b/src/journal/journald-syslog.h
@@ -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
index 0000000000..d6b9be5974
--- /dev/null
+++ b/src/journal/journald.c
@@ -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
index 0000000000..948318bc62
--- /dev/null
+++ b/src/journal/journald.conf
@@ -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
index 0000000000..9883595644
--- /dev/null
+++ b/src/journal/libsystemd-journal.pc.in
@@ -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
index 0000000000..ad78fcc74d
--- /dev/null
+++ b/src/journal/libsystemd-journal.sym
@@ -0,0 +1,87 @@
+/***
+ 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;
+} LIBSYSTEMD_JOURNAL_195;
diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c
new file mode 100644
index 0000000000..52ffdf7b1d
--- /dev/null
+++ b/src/journal/lookup3.c
@@ -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
index 0000000000..502b42c209
--- /dev/null
+++ b/src/journal/lookup3.h
@@ -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
index 0000000000..251aefe121
--- /dev/null
+++ b/src/journal/mmap-cache.c
@@ -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
index 0000000000..0c42fb88e6
--- /dev/null
+++ b/src/journal/mmap-cache.h
@@ -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
index 0000000000..a346691e21
--- /dev/null
+++ b/src/journal/sd-journal.c
@@ -0,0 +1,2391 @@
+/*-*- 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"
+
+#define JOURNAL_FILES_MAX 1024
+
+#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC)
+
+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 =
+ sfs.f_type == 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;
+
+ 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))
+ 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 0;
+ }
+
+ r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+ if (r < 0)
+ return r;
+ }
+
+ return -ENOENT;
+}
+
+static int return_data(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))
+ 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(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->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->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;
+}
diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c
new file mode 100644
index 0000000000..8a843ecdda
--- /dev/null
+++ b/src/journal/test-journal-enum.c
@@ -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
index 0000000000..fa228144f5
--- /dev/null
+++ b/src/journal/test-journal-match.c
@@ -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
index 0000000000..3e986ed99a
--- /dev/null
+++ b/src/journal/test-journal-send.c
@@ -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
index 0000000000..b3e816db70
--- /dev/null
+++ b/src/journal/test-journal-stream.c
@@ -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
index 0000000000..3ae8633f22
--- /dev/null
+++ b/src/journal/test-journal-syslog.c
@@ -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
index 0000000000..b6677215c0
--- /dev/null
+++ b/src/journal/test-journal-verify.c
@@ -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
index 0000000000..f4dc52cd81
--- /dev/null
+++ b/src/journal/test-journal.c
@@ -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
index 0000000000..e2ffaf4723
--- /dev/null
+++ b/src/journal/test-mmap-cache.c
@@ -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
index 0000000000..5184131b28
--- /dev/null
+++ b/src/libsystemd-daemon/.gitignore
@@ -0,0 +1 @@
+/libsystemd-daemon.pc
diff --git a/src/libsystemd-daemon/Makefile b/src/libsystemd-daemon/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/libsystemd-daemon/Makefile
@@ -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
index 0000000000..8bb3a74c87
--- /dev/null
+++ b/src/libsystemd-daemon/libsystemd-daemon.pc.in
@@ -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
index 0000000000..f440238931
--- /dev/null
+++ b/src/libsystemd-daemon/libsystemd-daemon.sym
@@ -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
index 0000000000..4801d2cd18
--- /dev/null
+++ b/src/libsystemd-daemon/sd-daemon.c
@@ -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
index 0000000000..144adf9bea
--- /dev/null
+++ b/src/libsystemd-id128/.gitignore
@@ -0,0 +1 @@
+/libsystemd-id128.pc
diff --git a/src/libsystemd-id128/Makefile b/src/libsystemd-id128/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/libsystemd-id128/Makefile
@@ -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
index 0000000000..bb65ffde33
--- /dev/null
+++ b/src/libsystemd-id128/libsystemd-id128.pc.in
@@ -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
index 0000000000..604c0026c6
--- /dev/null
+++ b/src/libsystemd-id128/libsystemd-id128.sym
@@ -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
index 0000000000..4286ae7d14
--- /dev/null
+++ b/src/libsystemd-id128/sd-id128.c
@@ -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
index 0000000000..0c8a5d5231
--- /dev/null
+++ b/src/libudev/.gitignore
@@ -0,0 +1 @@
+/libudev.pc
diff --git a/src/libudev/Makefile b/src/libudev/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/libudev/Makefile
@@ -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
index 0000000000..c123057907
--- /dev/null
+++ b/src/libudev/libudev-device-private.c
@@ -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
index 0000000000..acf8e24d15
--- /dev/null
+++ b/src/libudev/libudev-device.c
@@ -0,0 +1,1758 @@
+/***
+ 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;
+ 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;
+}
+
+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 {
+ 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 link to a device and return its syspath */
+ 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
index 0000000000..172965511b
--- /dev/null
+++ b/src/libudev/libudev-enumerate.c
@@ -0,0 +1,956 @@
+/***
+ 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;
+
+ 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
index 0000000000..e167e2805b
--- /dev/null
+++ b/src/libudev/libudev-hwdb-def.h
@@ -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 */
+_packed_ 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;
+};
+
+/* array of child entries, follows directly the node record */
+_packed_ 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;
+};
+
+/* array of value entries, follows directly the node record/child array */
+_packed_ struct trie_value_entry_f {
+ le64_t key_off;
+ le64_t value_off;
+};
+
+#endif
diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c
new file mode 100644
index 0000000000..751b34209e
--- /dev/null
+++ b/src/libudev/libudev-hwdb.c
@@ -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 (node->values_count && fnmatch(linebuf_get(buf), search, 0) == 0)
+ for (i = 0; i < 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 < 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("/etc/udev/hwdb.bin", "re");
+ if (!hwdb->f) {
+ log_debug("error reading /etc/udev/hwdb.bin: %m");
+ 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 /etc/udev/hwdb.bin: %m");
+ 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 /etc/udev/hwdb.bin: %m");
+ 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 /etc/udev/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->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
index 0000000000..59ba69e279
--- /dev/null
+++ b/src/libudev/libudev-list.c
@@ -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
index 0000000000..b02ea8808c
--- /dev/null
+++ b/src/libudev/libudev-monitor.c
@@ -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
index 0000000000..ff1cc8cefd
--- /dev/null
+++ b/src/libudev/libudev-private.h
@@ -0,0 +1,180 @@
+/***
+ 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);
+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_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
index 0000000000..80d7ceef2b
--- /dev/null
+++ b/src/libudev/libudev-queue-private.c
@@ -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
index 0000000000..08d52ab1f1
--- /dev/null
+++ b/src/libudev/libudev-queue.c
@@ -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
index 0000000000..cb9ed9c84b
--- /dev/null
+++ b/src/libudev/libudev-util.c
@@ -0,0 +1,725 @@
+/***
+ 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;
+ *dest[0] = '\0';
+ } else {
+ if (len > 0) {
+ *dest = mempcpy(*dest, src, len);
+ size -= len;
+ }
+ *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
index 0000000000..d860ebc080
--- /dev/null
+++ b/src/libudev/libudev.c
@@ -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
index 0000000000..bb41532a21
--- /dev/null
+++ b/src/libudev/libudev.h
@@ -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
index 0000000000..dad7139c85
--- /dev/null
+++ b/src/libudev/libudev.pc.in
@@ -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
index 0000000000..df6a1aeddf
--- /dev/null
+++ b/src/libudev/libudev.sym
@@ -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
index 0000000000..b1e0ba755e
--- /dev/null
+++ b/src/locale/.gitignore
@@ -0,0 +1 @@
+org.freedesktop.locale1.policy
diff --git a/src/locale/Makefile b/src/locale/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/locale/Makefile
@@ -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
index 0000000000..624c5179fa
--- /dev/null
+++ b/src/locale/generate-kbd-model-map
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+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
index 0000000000..a895880269
--- /dev/null
+++ b/src/locale/kbd-model-map
@@ -0,0 +1,72 @@
+# 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 mkd,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(fr) 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
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
new file mode 100644
index 0000000000..fa73bcaac6
--- /dev/null
+++ b/src/locale/localectl.c
@@ -0,0 +1,781 @@
+/*-*- 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 > 3 ? 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(DISTRIBUTION);
+ 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
index 0000000000..04268a1982
--- /dev/null
+++ b/src/locale/localed.c
@@ -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_parents_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
index 0000000000..79d0ecd2bb
--- /dev/null
+++ b/src/locale/org.freedesktop.locale1.conf
@@ -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
index 0000000000..91296c2356
--- /dev/null
+++ b/src/locale/org.freedesktop.locale1.policy.in
@@ -0,0 +1,39 @@
+<?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>
+ </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
index 0000000000..025f9a0fc2
--- /dev/null
+++ b/src/locale/org.freedesktop.locale1.service
@@ -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
index 0000000000..d3840c7afc
--- /dev/null
+++ b/src/login/.gitignore
@@ -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
index 0000000000..36fb827315
--- /dev/null
+++ b/src/login/70-power-switch.rules
@@ -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
index 0000000000..d1275f2ca9
--- /dev/null
+++ b/src/login/70-uaccess.rules
@@ -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
index 0000000000..f554d7f615
--- /dev/null
+++ b/src/login/71-seat.rules.in
@@ -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
index 0000000000..901df750fd
--- /dev/null
+++ b/src/login/73-seat-late.rules.in
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/login/Makefile
@@ -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
index 0000000000..4735df7d3b
--- /dev/null
+++ b/src/login/inhibit.c
@@ -0,0 +1,332 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..7b2a7245fc
--- /dev/null
+++ b/src/login/libsystemd-login.pc.in
@@ -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
index 0000000000..ff51be729b
--- /dev/null
+++ b/src/login/libsystemd-login.sym
@@ -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
index 0000000000..146986b46e
--- /dev/null
+++ b/src/login/loginctl.c
@@ -0,0 +1,1611 @@
+/*-*- 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_PRETTY_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_pretty(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_PRETTY_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_pretty(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(DISTRIBUTION);
+ 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
index 0000000000..cb045a9928
--- /dev/null
+++ b/src/login/logind-acl.c
@@ -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
index 0000000000..ec09843a78
--- /dev/null
+++ b/src/login/logind-acl.h
@@ -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-button.c b/src/login/logind-button.c
new file mode 100644
index 0000000000..8bbd731ae4
--- /dev/null
+++ b/src/login/logind-button.c
@@ -0,0 +1,322 @@
+/*-*- 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,
+ HandleButton handle,
+ bool ignore_inhibited,
+ bool is_edge) {
+
+ static const char * const message_table[_HANDLE_BUTTON_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_BUTTON_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;
+
+ assert(b);
+
+ /* If the key handling is turned off, don't do anything */
+ if (handle == HANDLE_IGNORE) {
+ log_debug("Refusing key handling, as it is turned off.");
+ return 0;
+ }
+
+ /* If the key handling is inhibited, don't do anything */
+ if (manager_is_inhibited(b->manager, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0)) {
+ log_debug("Refusing key handling, %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(b->manager, 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(b->manager, 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]);
+
+ /* 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;
+
+ dbus_error_init(&error);
+ r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, 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;
+}
+
+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);
+}
+
+static const char* const handle_button_table[_HANDLE_BUTTON_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_button, HandleButton);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");
diff --git a/src/login/logind-button.h b/src/login/logind-button.h
new file mode 100644
index 0000000000..b76ca32c08
--- /dev/null
+++ b/src/login/logind-button.h
@@ -0,0 +1,67 @@
+/*-*- 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;
+
+typedef enum HandleButton {
+ HANDLE_IGNORE,
+ HANDLE_POWEROFF,
+ HANDLE_REBOOT,
+ HANDLE_HALT,
+ HANDLE_KEXEC,
+ HANDLE_SUSPEND,
+ HANDLE_HIBERNATE,
+ HANDLE_HYBRID_SLEEP,
+ HANDLE_LOCK,
+ _HANDLE_BUTTON_MAX,
+ _HANDLE_BUTTON_INVALID = -1
+} HandleButton;
+
+#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);
+
+const char* handle_button_to_string(HandleButton h);
+HandleButton handle_button_from_string(const char *s);
+
+int config_parse_handle_button(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-dbus.c b/src/login/logind-dbus.c
new file mode 100644
index 0000000000..8b6021d35f
--- /dev/null
+++ b/src/login/logind-dbus.c
@@ -0,0 +1,2389 @@
+/*-*- 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=\"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_button, handle_button, HandleButton);
+
+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_button, "s", offsetof(Manager, handle_power_key) },
+ { "HandleSuspendKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_suspend_key) },
+ { "HandleHibernateKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_hibernate_key)},
+ { "HandleLidSwitch", bus_manager_append_handle_button, "s", offsetof(Manager, handle_lid_switch) },
+ { "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 (!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;
+}
+
+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
index 0000000000..51b15358ba
--- /dev/null
+++ b/src/login/logind-device.c
@@ -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
index 0000000000..3b153568cb
--- /dev/null
+++ b/src/login/logind-device.h
@@ -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
index 0000000000..1bd1b285d8
--- /dev/null
+++ b/src/login/logind-gperf.gperf
@@ -0,0 +1,32 @@
+%{
+#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_button, 0, offsetof(Manager, handle_power_key)
+Login.HandleSuspendKey, config_parse_handle_button, 0, offsetof(Manager, handle_suspend_key)
+Login.HandleHibernateKey, config_parse_handle_button, 0, offsetof(Manager, handle_hibernate_key)
+Login.HandleLidSwitch, config_parse_handle_button, 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)
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
new file mode 100644
index 0000000000..f1b9cca834
--- /dev/null
+++ b/src/login/logind-inhibit.c
@@ -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
index 0000000000..4c158ee0fe
--- /dev/null
+++ b/src/login/logind-inhibit.h
@@ -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
index 0000000000..7833d70a03
--- /dev/null
+++ b/src/login/logind-seat-dbus.c
@@ -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
index 0000000000..470d08bc05
--- /dev/null
+++ b/src/login/logind-seat.c
@@ -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
index 0000000000..c8ab17f7cf
--- /dev/null
+++ b/src/login/logind-seat.h
@@ -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
index 0000000000..ef73cd434a
--- /dev/null
+++ b/src/login/logind-session-dbus.c
@@ -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
index 0000000000..5d9401b223
--- /dev/null
+++ b/src/login/logind-session.c
@@ -0,0 +1,1010 @@
+/*-*- 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"
+
+#define IDLE_THRESHOLD_USEC (5*USEC_PER_MINUTE)
+
+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;
+}
+
+int session_get_idle_hint(Session *s, dual_timestamp *t) {
+ char *p;
+ struct stat st;
+ usec_t u, n;
+ int k;
+
+ assert(s);
+
+ if (s->idle_hint) {
+ if (t)
+ *t = s->idle_hint_timestamp;
+
+ return s->idle_hint;
+ }
+
+ if (isempty(s->tty))
+ goto dont_know;
+
+ if (s->tty[0] != '/') {
+ p = strappend("/dev/", s->tty);
+ if (!p)
+ return -ENOMEM;
+ } else
+ p = NULL;
+
+ if (!startswith(p ? p : s->tty, "/dev/")) {
+ free(p);
+ goto dont_know;
+ }
+
+ k = lstat(p ? p : s->tty, &st);
+ free(p);
+
+ if (k < 0)
+ goto dont_know;
+
+ u = timespec_load(&st.st_atim);
+ n = now(CLOCK_REALTIME);
+
+ if (t)
+ dual_timestamp_from_realtime(t, u);
+
+ return u + IDLE_THRESHOLD_USEC < n;
+
+dont_know:
+ if (t)
+ *t = s->idle_hint_timestamp;
+
+ return 0;
+}
+
+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
index 0000000000..7598afa618
--- /dev/null
+++ b/src/login/logind-session.h
@@ -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
index 0000000000..ddf9d9d5cf
--- /dev/null
+++ b/src/login/logind-user-dbus.c
@@ -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
index 0000000000..b692b533e2
--- /dev/null
+++ b/src/login/logind-user.c
@@ -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
index 0000000000..a679d43a30
--- /dev/null
+++ b/src/login/logind-user.h
@@ -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
index 0000000000..9cce481340
--- /dev/null
+++ b/src/login/logind.c
@@ -0,0 +1,1680 @@
+/*-*- 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 <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->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);
+
+ 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_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);
+
+ 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_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
index 0000000000..2757fba30a
--- /dev/null
+++ b/src/login/logind.conf
@@ -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.
+#
+# 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
diff --git a/src/login/logind.h b/src/login/logind.h
new file mode 100644
index 0000000000..f415dfbcbf
--- /dev/null
+++ b/src/login/logind.h
@@ -0,0 +1,174 @@
+/*-*- 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"
+
+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;
+
+ HandleButton handle_power_key;
+ HandleButton handle_suspend_key;
+ HandleButton handle_hibernate_key;
+ HandleButton 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_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_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
index 0000000000..83760d4191
--- /dev/null
+++ b/src/login/multi-seat-x.c
@@ -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
index 0000000000..5860fd9226
--- /dev/null
+++ b/src/login/org.freedesktop.login1.conf
@@ -0,0 +1,142 @@
+<?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="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="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
index 0000000000..57dfb2a8b6
--- /dev/null
+++ b/src/login/org.freedesktop.login1.policy.in
@@ -0,0 +1,259 @@
+<?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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </action>
+
+</policyconfig>
diff --git a/src/login/org.freedesktop.login1.service b/src/login/org.freedesktop.login1.service
new file mode 100644
index 0000000000..762dae2bb3
--- /dev/null
+++ b/src/login/org.freedesktop.login1.service
@@ -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
index 0000000000..08a9328b65
--- /dev/null
+++ b/src/login/pam-module.c
@@ -0,0 +1,716 @@
+/*-*- 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,
+ 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], "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, *class, *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,
+ &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 cannot stop doing that for compatibility reasons. */
+ 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);
+ }
+
+ 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 = "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
index 0000000000..45e3bb8dcd
--- /dev/null
+++ b/src/login/sd-login.c
@@ -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
index 0000000000..d113ec3e43
--- /dev/null
+++ b/src/login/sysfs-show.c
@@ -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
index 0000000000..7b6deffc3e
--- /dev/null
+++ b/src/login/test-inhibit.c
@@ -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
index 0000000000..159ff3efc5
--- /dev/null
+++ b/src/login/test-login.c
@@ -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
index 0000000000..2c530c8f39
--- /dev/null
+++ b/src/login/uaccess.c
@@ -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
index 0000000000..91531e8f38
--- /dev/null
+++ b/src/login/user-sessions.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/machine-id-setup/Makefile
@@ -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
index 0000000000..6373ebc2db
--- /dev/null
+++ b/src/machine-id-setup/machine-id-setup-main.c
@@ -0,0 +1,102 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/modules-load/Makefile
@@ -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
index 0000000000..e72e382e19
--- /dev/null
+++ b/src/modules-load/modules-load.c
@@ -0,0 +1,266 @@
+/*-*- 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 *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, "modules-load=")) {
+
+ r = add_modules(word + 13);
+ if (r < 0)
+ goto finish;
+
+ } else if (startswith(word, "rd.modules-load=")) {
+
+ if (in_initrd()) {
+ r = add_modules(word + 16);
+ if (r < 0)
+ goto finish;
+ }
+
+ }
+
+ free(word);
+ }
+
+ r = 0;
+
+finish:
+ free(line);
+ return r;
+}
+
+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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/notify/Makefile
@@ -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
index 0000000000..ffc8dfeb9b
--- /dev/null
+++ b/src/notify/notify.c
@@ -0,0 +1,228 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/nspawn/Makefile
@@ -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
index 0000000000..244ebb8342
--- /dev/null
+++ b/src/nspawn/nspawn.c
@@ -0,0 +1,1444 @@
+/*-*- 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"
+
+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, 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;
+
+ 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;
+ }
+
+ 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(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, STDIN_FILENO, &stdin_ev) < 0 ||
+ 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 regiser 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 {
+ 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;
+ 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 };
+
+ 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;
+ }
+
+ 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) {
+ log_error("Failed to get terminal attributes: %m");
+ goto finish;
+ }
+
+ 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 (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;
+ 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
+ };
+
+ envp[2] = strv_find_prefix(environ, "TERM=");
+
+ close_nointr_nofail(master);
+
+ close_nointr(STDIN_FILENO);
+ close_nointr(STDOUT_FILENO);
+ close_nointr(STDERR_FILENO);
+
+ close_all_fds(&kmsg_socket_pair[1], 1);
+
+ reset_all_signal_handlers();
+
+ assert_se(sigemptyset(&mask) == 0);
+ assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+ if (open_terminal(console, O_RDWR) != STDIN_FILENO ||
+ dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
+ dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
+ 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]);
+
+ 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;
+ }
+ }
+
+ if ((asprintf((char**)(envp + 3), "HOME=%s", home ? home: "/root") < 0) ||
+ (asprintf((char**)(envp + 4), "USER=%s", arg_user ? arg_user : "root") < 0) ||
+ (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
+ log_oom();
+ goto child_fail;
+ }
+
+ if (arg_uuid) {
+ if (asprintf((char**)(envp + 6), "container_uuid=%s", arg_uuid) < 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);
+ }
+
+ if (process_pty(master, &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);
+
+ return r;
+}
diff --git a/src/python-systemd/Makefile b/src/python-systemd/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/python-systemd/Makefile
@@ -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
index 0000000000..0d56b992f4
--- /dev/null
+++ b/src/python-systemd/__init__.py
@@ -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
index 0000000000..0bdf709aea
--- /dev/null
+++ b/src/python-systemd/_journal.c
@@ -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
index 0000000000..516ca1ab56
--- /dev/null
+++ b/src/python-systemd/journal.py
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/quotacheck/Makefile
@@ -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
index 0000000000..05e4971487
--- /dev/null
+++ b/src/quotacheck/quotacheck.c
@@ -0,0 +1,120 @@
+/*-*- 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.");
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+ else if (strneq(w, "forcequotacheck", l))
+ arg_force = true;
+#endif
+ }
+
+ free(line);
+ return 0;
+}
+
+static void test_files(void) {
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+ /* This exists only on Fedora, Mandriva or Mageia */
+ if (access("/forcequotacheck", F_OK) >= 0)
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/random-seed/Makefile
@@ -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
index 0000000000..fdcaa1e154
--- /dev/null
+++ b/src/random-seed/random-seed.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/rc-local-generator/Makefile
@@ -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
index 0000000000..c219e77047
--- /dev/null
+++ b/src/rc-local-generator/rc-local-generator.c
@@ -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"
+
+#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+#define SCRIPT_PATH_START "/etc/rc.d/rc.local"
+#elif defined(TARGET_SUSE)
+#define SCRIPT_PATH_START "/etc/init.d/boot.local"
+#endif
+
+#define SCRIPT_PATH_STOP "/sbin/halt.local"
+
+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(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(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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/readahead/Makefile
@@ -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
index 0000000000..9a929c0937
--- /dev/null
+++ b/src/readahead/readahead-analyze.c
@@ -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
index 0000000000..5d07f4704a
--- /dev/null
+++ b/src/readahead/readahead-collect.c
@@ -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
index 0000000000..10b0ccc548
--- /dev/null
+++ b/src/readahead/readahead-common.c
@@ -0,0 +1,359 @@
+/*-*- 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"
+
+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;
+
+ assert(p);
+
+ if (stat(p, &st) < 0)
+ return -errno;
+
+ if (major(st.st_dev) == 0)
+ 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)
+ if ((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
index 0000000000..b34f3aadd7
--- /dev/null
+++ b/src/readahead/readahead-common.h
@@ -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
index 0000000000..a1ac6b0c91
--- /dev/null
+++ b/src/readahead/readahead-replay.c
@@ -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)
+ 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
index 0000000000..abeecc7634
--- /dev/null
+++ b/src/readahead/readahead.c
@@ -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
index 0000000000..d48cd76807
--- /dev/null
+++ b/src/readahead/sd-readahead.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/remount-fs/Makefile
@@ -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
index 0000000000..b49d095cbb
--- /dev/null
+++ b/src/remount-fs/remount-fs.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/reply-password/Makefile
@@ -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
index 0000000000..a935d0f084
--- /dev/null
+++ b/src/reply-password/reply-password.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/shared/Makefile
@@ -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
index 0000000000..d1eb6f2268
--- /dev/null
+++ b/src/shared/acl-util.c
@@ -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
index 0000000000..31fbbcd510
--- /dev/null
+++ b/src/shared/acl-util.h
@@ -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
index 0000000000..8a0fb89a84
--- /dev/null
+++ b/src/shared/ask-password-api.c
@@ -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
index 0000000000..288a0f48cf
--- /dev/null
+++ b/src/shared/ask-password-api.h
@@ -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
index 0000000000..e5c483ab08
--- /dev/null
+++ b/src/shared/audit.c
@@ -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
index 0000000000..490a0b0320
--- /dev/null
+++ b/src/shared/audit.h
@@ -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/capability.c b/src/shared/capability.c
new file mode 100644
index 0000000000..9b743e86d0
--- /dev/null
+++ b/src/shared/capability.c
@@ -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
index 0000000000..6cb31bb510
--- /dev/null
+++ b/src/shared/capability.h
@@ -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
index 0000000000..beeeec5830
--- /dev/null
+++ b/src/shared/cgroup-label.c
@@ -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
index 0000000000..437d09711b
--- /dev/null
+++ b/src/shared/cgroup-show.c
@@ -0,0 +1,351 @@
+/*-*- 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;
+ char *controller, *path;
+
+ assert(spec);
+
+ r = cg_split_spec(spec, &controller, &path);
+ if (r < 0)
+ return r;
+
+ r = show_cgroup_and_extra(controller, path, prefix, n_columns, kernel_threads, all, extra_pids, n_extra_pids);
+ free(controller);
+ free(path);
+
+ return r;
+}
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
new file mode 100644
index 0000000000..dba900a153
--- /dev/null
+++ b/src/shared/cgroup-show.h
@@ -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
index 0000000000..b0d378de5a
--- /dev/null
+++ b/src/shared/cgroup-util.c
@@ -0,0 +1,1256 @@
+/*-*- 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_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
index 0000000000..697669deba
--- /dev/null
+++ b/src/shared/cgroup-util.h
@@ -0,0 +1,74 @@
+/*-*- 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_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
index 0000000000..34b86293d3
--- /dev/null
+++ b/src/shared/conf-files.c
@@ -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
index 0000000000..f37ee1f3db
--- /dev/null
+++ b/src/shared/conf-files.h
@@ -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
index 0000000000..9f5c07c761
--- /dev/null
+++ b/src/shared/conf-parser.c
@@ -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
index 0000000000..56ffc2f8a8
--- /dev/null
+++ b/src/shared/conf-parser.h
@@ -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
index 0000000000..ee281e57f4
--- /dev/null
+++ b/src/shared/dbus-common.c
@@ -0,0 +1,1326 @@
+/*-*- 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 (!dbus_connection_send(c, reply, NULL))
+ 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;
+}
+
+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 (!dbus_connection_send(c, reply, NULL))
+ 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
index 0000000000..005a715d0a
--- /dev/null
+++ b/src/shared/dbus-common.h
@@ -0,0 +1,222 @@
+/*-*- 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>
+
+#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;
+
+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)))
diff --git a/src/shared/dbus-loop.c b/src/shared/dbus-loop.c
new file mode 100644
index 0000000000..da0a00443a
--- /dev/null
+++ b/src/shared/dbus-loop.c
@@ -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
index 0000000000..a5e768d931
--- /dev/null
+++ b/src/shared/dbus-loop.h
@@ -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
index 0000000000..5ba170f965
--- /dev/null
+++ b/src/shared/def.h
@@ -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
index 0000000000..b0ac02d461
--- /dev/null
+++ b/src/shared/dev-setup.c
@@ -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
index 0000000000..320c0b30ba
--- /dev/null
+++ b/src/shared/dev-setup.h
@@ -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
index 0000000000..45131f2b2a
--- /dev/null
+++ b/src/shared/exit-status.c
@@ -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
index 0000000000..d3b548fc96
--- /dev/null
+++ b/src/shared/exit-status.h
@@ -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/hashmap.c b/src/shared/hashmap.c
new file mode 100644
index 0000000000..dcfbb67228
--- /dev/null
+++ b/src/shared/hashmap.c
@@ -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;
+}
+
+#ifndef __OPTIMIZE__
+
+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
index 0000000000..6fd71cf519
--- /dev/null
+++ b/src/shared/hashmap.h
@@ -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
index 0000000000..f9adf0369e
--- /dev/null
+++ b/src/shared/hwclock.c
@@ -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
index 0000000000..b2bdc78f0c
--- /dev/null
+++ b/src/shared/hwclock.h
@@ -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
index 0000000000..a9d75f3b7c
--- /dev/null
+++ b/src/shared/install.c
@@ -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
index 0000000000..55249914b1
--- /dev/null
+++ b/src/shared/install.h
@@ -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
index 0000000000..9800fc2553
--- /dev/null
+++ b/src/shared/ioprio.h
@@ -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
index 0000000000..d353da57ec
--- /dev/null
+++ b/src/shared/label.c
@@ -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
index 0000000000..1220b18965
--- /dev/null
+++ b/src/shared/label.h
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/shared/linux/Makefile
@@ -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
index 0000000000..850f39b33e
--- /dev/null
+++ b/src/shared/linux/auto_dev-ioctl.h
@@ -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
index 0000000000..63531a6b4d
--- /dev/null
+++ b/src/shared/linux/fanotify.h
@@ -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
index 0000000000..1e3d136739
--- /dev/null
+++ b/src/shared/linux/seccomp-bpf.h
@@ -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
index 0000000000..9c03683fa0
--- /dev/null
+++ b/src/shared/linux/seccomp.h
@@ -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
index 0000000000..47f275a019
--- /dev/null
+++ b/src/shared/list.h
@@ -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
index 0000000000..63578683ab
--- /dev/null
+++ b/src/shared/log.c
@@ -0,0 +1,885 @@
+/*-*- 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 *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 *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);
+ if (!(tm = localtime(&t)))
+ 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 *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 *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"
+ "SYSLOG_IDENTIFIER=%s\n"
+ "MESSAGE=",
+ LOG_PRI(level),
+ LOG_FAC(level),
+ file,
+ line,
+ func,
+ 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,
+ 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, 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, 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, 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, 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, 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, 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;
+}
+
+#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, 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, 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
index 0000000000..1bd9dbf27a
--- /dev/null
+++ b/src/shared/log.h
@@ -0,0 +1,139 @@
+/*-*- 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"
+
+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_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
index 0000000000..36cce73550
--- /dev/null
+++ b/src/shared/logs-show.c
@@ -0,0 +1,904 @@
+/*-*- 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 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_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 (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);
+
+ 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);
+
+ 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);
+ }
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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
index 0000000000..06082800c8
--- /dev/null
+++ b/src/shared/logs-show.h
@@ -0,0 +1,74 @@
+/*-*- 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
+} 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
index 0000000000..e930fdab53
--- /dev/null
+++ b/src/shared/macro.h
@@ -0,0 +1,242 @@
+/*-*- 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)
+
+#define assert_cc(expr) \
+ do { \
+ switch (0) { \
+ case 0: \
+ case !!(expr): \
+ ; \
+ } \
+ } while (false)
+
+#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
index 0000000000..3777cf69b2
--- /dev/null
+++ b/src/shared/missing.h
@@ -0,0 +1,255 @@
+/*-*- 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
diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c
new file mode 100644
index 0000000000..0e51b64f69
--- /dev/null
+++ b/src/shared/mkdir.c
@@ -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
index 0000000000..ce1c35e9ba
--- /dev/null
+++ b/src/shared/mkdir.h
@@ -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
index 0000000000..488a12c763
--- /dev/null
+++ b/src/shared/pager.c
@@ -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
index 0000000000..5e7b5ab91e
--- /dev/null
+++ b/src/shared/pager.h
@@ -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
index 0000000000..6e5529e0c7
--- /dev/null
+++ b/src/shared/path-lookup.c
@@ -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
index 0000000000..baef62228a
--- /dev/null
+++ b/src/shared/path-lookup.h
@@ -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
index 0000000000..70c8a8af06
--- /dev/null
+++ b/src/shared/path-util.c
@@ -0,0 +1,419 @@
+/*-*- 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);
+
+ 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
index 0000000000..e81821a28f
--- /dev/null
+++ b/src/shared/path-util.h
@@ -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
index 0000000000..126096e64f
--- /dev/null
+++ b/src/shared/polkit.c
@@ -0,0 +1,163 @@
+/*-*- 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) {
+ r = -EIO;
+ goto finish;
+ }
+
+ if (dbus_set_error_from_message(error, reply)) {
+ 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
index 0000000000..6255d1f617
--- /dev/null
+++ b/src/shared/polkit.h
@@ -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
index 0000000000..1054d52f97
--- /dev/null
+++ b/src/shared/ratelimit.c
@@ -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
index 0000000000..58efca7df1
--- /dev/null
+++ b/src/shared/ratelimit.h
@@ -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
index 0000000000..e11c57a43d
--- /dev/null
+++ b/src/shared/replace-var.c
@@ -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
index 0000000000..7eaee93a3e
--- /dev/null
+++ b/src/shared/replace-var.h
@@ -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
index 0000000000..ff3375607f
--- /dev/null
+++ b/src/shared/selinux-util.c
@@ -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
index 0000000000..4b81202741
--- /dev/null
+++ b/src/shared/selinux-util.h
@@ -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
index 0000000000..5f83c50839
--- /dev/null
+++ b/src/shared/set.c
@@ -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
index 0000000000..9162e2ae80
--- /dev/null
+++ b/src/shared/set.h
@@ -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
index 0000000000..ff212de825
--- /dev/null
+++ b/src/shared/socket-label.c
@@ -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
index 0000000000..49ea75880d
--- /dev/null
+++ b/src/shared/socket-util.c
@@ -0,0 +1,544 @@
+/*-*- 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);
+
+ 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;
+}
+
+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
index 0000000000..04cfb83f5a
--- /dev/null
+++ b/src/shared/socket-util.h
@@ -0,0 +1,99 @@
+/*-*- 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_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
index 0000000000..eb4dbf3615
--- /dev/null
+++ b/src/shared/sparse-endian.h
@@ -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
index 0000000000..c1a9c58681
--- /dev/null
+++ b/src/shared/spawn-ask-password-agent.c
@@ -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
index 0000000000..31b4beab58
--- /dev/null
+++ b/src/shared/spawn-ask-password-agent.h
@@ -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
index 0000000000..fcb3722ddf
--- /dev/null
+++ b/src/shared/spawn-polkit-agent.c
@@ -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
index 0000000000..b91d20f120
--- /dev/null
+++ b/src/shared/spawn-polkit-agent.h
@@ -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
index 0000000000..599027cd47
--- /dev/null
+++ b/src/shared/specifier.c
@@ -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
index 0000000000..25a27a423f
--- /dev/null
+++ b/src/shared/specifier.h
@@ -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
index 0000000000..915cd3ac99
--- /dev/null
+++ b/src/shared/strbuf.c
@@ -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
index 0000000000..2347fd4328
--- /dev/null
+++ b/src/shared/strbuf.h
@@ -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
index 0000000000..6b76d0eaef
--- /dev/null
+++ b/src/shared/strv.c
@@ -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
index 0000000000..45558d8960
--- /dev/null
+++ b/src/shared/strv.h
@@ -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
index 0000000000..afc893cccc
--- /dev/null
+++ b/src/shared/time-dst.c
@@ -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
index 0000000000..536b6bbdfb
--- /dev/null
+++ b/src/shared/time-dst.h
@@ -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/unit-name.c b/src/shared/unit-name.c
new file mode 100644
index 0000000000..50031e608e
--- /dev/null
+++ b/src/shared/unit-name.c
@@ -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" \
+ ":-_.\\"
+
+static 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);
+
+static 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
index 0000000000..7be346590e
--- /dev/null
+++ b/src/shared/unit-name.h
@@ -0,0 +1,94 @@
+/*-*- 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,
+ UNIT_LOADED,
+ UNIT_ERROR,
+ UNIT_MERGED,
+ UNIT_MASKED,
+ _UNIT_LOAD_STATE_MAX,
+ _UNIT_LOAD_STATE_INVALID = -1
+};
+
+const char *unit_type_to_string(UnitType i);
+UnitType unit_type_from_string(const char *s);
+
+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
index 0000000000..5f9f3c60c5
--- /dev/null
+++ b/src/shared/utf8.c
@@ -0,0 +1,286 @@
+/*-*- 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 Lesser 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
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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
index 0000000000..13d2f6a980
--- /dev/null
+++ b/src/shared/utf8.h
@@ -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
index 0000000000..6d826b6f5e
--- /dev/null
+++ b/src/shared/util.c
@@ -0,0 +1,6215 @@
+/*-*- 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;
+}
+
+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* 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;
+}
+
+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_pretty(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 and %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 and %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 and %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 and %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;
+}
+
+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_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;
+}
+
+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;
+
+ *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);
+
+ if ((k = readlink_malloc(fn, &s)) < 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. */
+
+ if (!(b = strdup(fn + 5)))
+ 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;
+}
+
+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 (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ 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 (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ 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 (s.f_type != TMPFS_MAGIC &&
+ s.f_type != RAMFS_MAGIC) {
+ 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;
+ unsigned c;
+
+ if (_likely_(cached_columns > 0))
+ return cached_columns;
+
+ c = 0;
+ e = getenv("COLUMNS");
+ if (e)
+ safe_atou(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;
+}
+
+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;
+ }
+}
+
+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);
+
+ r = read_one_line_file("/sys/power/state", &p);
+ if (r < 0)
+ return r == -ENOENT ? 0 : r;
+
+ 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);
+
+ r = read_one_line_file("/sys/power/disk", &p);
+ if (r < 0)
+ return r == -ENOENT ? 0 : r;
+
+ 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 &&
+ (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
+
+ 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;
+}
+
+int parse_timestamp(const char *t, usec_t *usec) {
+ const char *k;
+ struct tm tm, copy;
+ time_t x;
+ usec_t plus = 0, minus = 0, ret;
+ int r;
+
+ /*
+ * 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));
+
+ 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;
+ }
+
+ 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;
+
+ ret = (usec_t) x * USEC_PER_SEC;
+
+ ret += plus;
+ if (ret > minus)
+ ret -= minus;
+ else
+ ret = 0;
+
+ *usec = ret;
+
+ return 0;
+}
+
+/* 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;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
new file mode 100644
index 0000000000..a148ebbc58
--- /dev/null
+++ b/src/shared/util.h
@@ -0,0 +1,615 @@
+/*-*- 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"
+
+typedef uint64_t usec_t;
+typedef uint64_t nsec_t;
+
+typedef struct dual_timestamp {
+ usec_t realtime;
+ usec_t monotonic;
+} dual_timestamp;
+
+union dirent_storage {
+ struct dirent de;
+ uint8_t storage[offsetof(struct dirent, d_name) +
+ ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))];
+};
+
+#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)
+
+/* What is interpreted as whitespace? */
+#define WHITESPACE " \t\n\r"
+#define NEWLINE "\n\r"
+#define QUOTES "\"\'"
+#define COMMENTS "#;\n"
+
+#define FORMAT_TIMESTAMP_MAX (5+11+9+4+1)
+#define FORMAT_TIMESTAMP_PRETTY_MAX 256
+#define FORMAT_TIMESPAN_MAX 64
+#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);
+
+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);
+
+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_usec(const char *t, usec_t *usec);
+int parse_nsec(const char *t, nsec_t *nsec);
+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);
+
+char *format_timestamp(char *buf, size_t l, usec_t t);
+char *format_timestamp_pretty(char *buf, size_t l, usec_t t);
+char *format_timespan(char *buf, size_t l, usec_t t);
+
+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);
+
+void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
+void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
+
+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);
+
+int parse_timestamp(const char *t, usec_t *usec);
+
+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);
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
new file mode 100644
index 0000000000..046fb584fb
--- /dev/null
+++ b/src/shared/utmp-wtmp.c
@@ -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
index 0000000000..5924023203
--- /dev/null
+++ b/src/shared/utmp-wtmp.h
@@ -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
index 0000000000..fc62c72328
--- /dev/null
+++ b/src/shared/virt.c
@@ -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
index 0000000000..aa6ad35ba9
--- /dev/null
+++ b/src/shared/virt.h
@@ -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
index 0000000000..13265e7692
--- /dev/null
+++ b/src/shared/watchdog.c
@@ -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
index 0000000000..b748b15857
--- /dev/null
+++ b/src/shared/watchdog.h
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/shutdownd/Makefile
@@ -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
index 0000000000..c0747415fd
--- /dev/null
+++ b/src/shutdownd/shutdownd.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/sleep/Makefile
@@ -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
index 0000000000..218de3a567
--- /dev/null
+++ b/src/sleep/sleep.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/stdio-bridge/Makefile
@@ -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
index 0000000000..f926fe5538
--- /dev/null
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/sysctl/Makefile
@@ -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
index 0000000000..035e0ec321
--- /dev/null
+++ b/src/sysctl/sysctl.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/system-update-generator/Makefile
@@ -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
index 0000000000..6660192f5e
--- /dev/null
+++ b/src/system-update-generator/system-update-generator.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/systemctl/Makefile
@@ -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
index 0000000000..b82c79435d
--- /dev/null
+++ b/src/systemctl/systemctl.c
@@ -0,0 +1,5354 @@
+/*-*- 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");
+ on = ansi_highlight(true);
+ off = ansi_highlight(false);
+ } else {
+ on = ansi_highlight_red(true);
+ off = ansi_highlight_red(false);
+ }
+
+ if (arg_all)
+ printf("\n%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("\n%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 -n' 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 -n' 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, 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 (streq(state, "active") || streq(state, "reloading"))
+ 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) {
+
+ 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);
+
+ r = check_one_unit(bus, service_trigger, true);
+ 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(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) {
+ int state = check_one_unit(bus, *name, arg_quiet);
+ 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_PRETTY_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_pretty(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_pretty(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) {
+ 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, *init;
+
+ l = strv_length(args);
+ if (l < 2 || l > 3) {
+ log_error("Wrong number of arguments.");
+ return -EINVAL;
+ }
+
+ root = args[1];
+ init = l >= 3 ? args[2] : "";
+
+ 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(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA))
+ 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 using systemctl.");
+
+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 is possible,\n"
+ " otherwise start or restart\n"
+ " reload-or-try-restart [NAME...] Reload one or more units is 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"
+ " 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 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(DISTRIBUTION);
+ puts(SYSTEMD_FEATURES);
+ return 0;
+
+ case 't':
+ 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);
+ 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 },
+ { "check", MORE, 2, check_unit },
+ { "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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/systemd/Makefile
@@ -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
index 0000000000..fb7456d50f
--- /dev/null
+++ b/src/systemd/sd-daemon.h
@@ -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
index 0000000000..79bb8b3c99
--- /dev/null
+++ b/src/systemd/sd-id128.h
@@ -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
index 0000000000..7241173035
--- /dev/null
+++ b/src/systemd/sd-journal.h
@@ -0,0 +1,149 @@
+/*-*- 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_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);
+
+#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
index 0000000000..6bd1f2da4a
--- /dev/null
+++ b/src/systemd/sd-login.h
@@ -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
index 0000000000..5099a36e6a
--- /dev/null
+++ b/src/systemd/sd-messages.h
@@ -0,0 +1,69 @@
+/*-*- 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
+
+#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)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/systemd/sd-readahead.h b/src/systemd/sd-readahead.h
new file mode 100644
index 0000000000..2dac104f7a
--- /dev/null
+++ b/src/systemd/sd-readahead.h
@@ -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
index 0000000000..cee4350173
--- /dev/null
+++ b/src/systemd/sd-shutdown.h
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/test/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c
new file mode 100644
index 0000000000..6d64a4e47f
--- /dev/null
+++ b/src/test/test-cgroup.c
@@ -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
index 0000000000..3215f0c560
--- /dev/null
+++ b/src/test/test-daemon.c
@@ -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
index 0000000000..57f8b371d3
--- /dev/null
+++ b/src/test/test-date.c
@@ -0,0 +1,69 @@
+/*-*- 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 "util.h"
+
+int main(int argc, char *argv[]) {
+
+ usec_t t;
+ char buf[FORMAT_TIMESTAMP_MAX];
+
+ assert_se(parse_timestamp("17:41", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("18:42:44", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("12-10-02 12:13:14", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("12-10-2 12:13:14", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("12-10-03 12:13", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("2012-12-30 18:42", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("2012-10-02", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("now", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("yesterday", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("today", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("tomorrow", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("+2d", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ assert_se(parse_timestamp("+2y 4d", &t) >= 0);
+ log_info("%s", format_timestamp(buf, sizeof(buf), t));
+
+ return 0;
+}
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
new file mode 100644
index 0000000000..0f3862226a
--- /dev/null
+++ b/src/test/test-engine.c
@@ -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
index 0000000000..cd596a6e16
--- /dev/null
+++ b/src/test/test-env-replace.c
@@ -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
index 0000000000..ad4f285619
--- /dev/null
+++ b/src/test/test-hostname.c
@@ -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
index 0000000000..bfd743eca3
--- /dev/null
+++ b/src/test/test-id128.c
@@ -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
index 0000000000..2c1b9efcb8
--- /dev/null
+++ b/src/test/test-install.c
@@ -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
index 0000000000..1066374436
--- /dev/null
+++ b/src/test/test-job-type.c
@@ -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
index 0000000000..caa3b4d14c
--- /dev/null
+++ b/src/test/test-libudev.c
@@ -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
index 0000000000..8dc3d5383f
--- /dev/null
+++ b/src/test/test-log.c
@@ -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
index 0000000000..ab330ac840
--- /dev/null
+++ b/src/test/test-loopback.c
@@ -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
index 0000000000..b1c759fc20
--- /dev/null
+++ b/src/test/test-ns.c
@@ -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
index 0000000000..b1d42d77fd
--- /dev/null
+++ b/src/test/test-replace-var.c
@@ -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-sleep.c b/src/test/test-sleep.c
new file mode 100644
index 0000000000..5a98ecda2f
--- /dev/null
+++ b/src/test/test-sleep.c
@@ -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-strv.c b/src/test/test-strv.c
new file mode 100644
index 0000000000..5ee4447669
--- /dev/null
+++ b/src/test/test-strv.c
@@ -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
index 0000000000..db9d36124e
--- /dev/null
+++ b/src/test/test-udev.c
@@ -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
index 0000000000..95e2b68015
--- /dev/null
+++ b/src/test/test-unit-file.c
@@ -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 <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "install.h"
+#include "util.h"
+#include "macro.h"
+#include "hashmap.h"
+
+int main(int argc, char *argv[]) {
+
+ 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);
+
+ return 0;
+}
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
new file mode 100644
index 0000000000..50187e1129
--- /dev/null
+++ b/src/test/test-unit-name.c
@@ -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
index 0000000000..ccb1854708
--- /dev/null
+++ b/src/test/test-watchdog.c
@@ -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
index 0000000000..48757f0968
--- /dev/null
+++ b/src/timedate/.gitignore
@@ -0,0 +1 @@
+org.freedesktop.timedate1.policy
diff --git a/src/timedate/Makefile b/src/timedate/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/timedate/Makefile
@@ -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
index 0000000000..36557d5841
--- /dev/null
+++ b/src/timedate/org.freedesktop.timedate1.conf
@@ -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
index 0000000000..dd0a54d81a
--- /dev/null
+++ b/src/timedate/org.freedesktop.timedate1.policy.in
@@ -0,0 +1,61 @@
+<?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>
+ </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
index 0000000000..875f4bec78
--- /dev/null
+++ b/src/timedate/org.freedesktop.timedate1.service
@@ -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
index 0000000000..c96377f829
--- /dev/null
+++ b/src/timedate/timedatectl.c
@@ -0,0 +1,719 @@
+/*-*- 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", localtime_r(&sec, &tm)) > 0);
+ char_array_0(a);
+ printf(" Timezone: %s\n"
+ " UTC offset: %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: %s → %s, DST became %s\n"
+ " %s\n"
+ " %s\n",
+ strna(zn), strna(zc), is_dstc ? "active" : "inactive", 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: %s → %s, DST will become %s\n"
+ " the clock will jump %s\n"
+ " %s\n"
+ " %s\n",
+ strna(zc), strna(zn), is_dstn ? "active" : "inactive", 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(DISTRIBUTION);
+ 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
index 0000000000..40ba255090
--- /dev/null
+++ b/src/timedate/timedated.c
@@ -0,0 +1,1042 @@
+/*-*- 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;
+
+#ifdef TARGET_DEBIAN
+ struct stat st;
+#endif
+
+ if (!tz.zone) {
+ if (unlink("/etc/localtime") < 0 && errno != ENOENT)
+ r = -errno;
+
+#ifdef TARGET_DEBIAN
+ if (unlink("/etc/timezone") < 0 && errno != ENOENT)
+ r = -errno;
+#endif
+
+ 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;
+
+#ifdef TARGET_DEBIAN
+ if (stat("/etc/timezone", &st) == 0 && S_ISREG(st.st_mode)) {
+ r = write_one_line_file_atomic("/etc/timezone", tz.zone);
+ if (r < 0)
+ return r;
+ }
+#endif
+
+ 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 fail;
+ }
+
+ 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);
+
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/timestamp/Makefile
@@ -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
index 0000000000..1152f1b52e
--- /dev/null
+++ b/src/timestamp/timestamp.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/tmpfiles/Makefile
@@ -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
index 0000000000..c27d0112f9
--- /dev/null
+++ b/src/tmpfiles/tmpfiles.c
@@ -0,0 +1,1418 @@
+/*-*- 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)
+ 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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/tty-ask-password-agent/Makefile
@@ -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
index 0000000000..052c10e7d5
--- /dev/null
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -0,0 +1,764 @@
+/*-*- 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(DISTRIBUTION);
+ 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
index 0000000000..3e375a7726
--- /dev/null
+++ b/src/udev/.gitignore
@@ -0,0 +1 @@
+/udev.pc
diff --git a/src/udev/.vimrc b/src/udev/.vimrc
new file mode 100644
index 0000000000..366fbdca4b
--- /dev/null
+++ b/src/udev/.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/src/udev/Makefile b/src/udev/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/udev/Makefile
@@ -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
index 0000000000..67fed27c5e
--- /dev/null
+++ b/src/udev/accelerometer/accelerometer.c
@@ -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 keymap; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
index 0000000000..488fed4ac4
--- /dev/null
+++ b/src/udev/ata_id/ata_id.c
@@ -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
index 0000000000..1056536b7d
--- /dev/null
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -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
index 0000000000..3c46e40de1
--- /dev/null
+++ b/src/udev/collect/collect.c
@@ -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
index 0000000000..4567584f4e
--- /dev/null
+++ b/src/udev/keymap/.gitignore
@@ -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
index 0000000000..39f01a4d3e
--- /dev/null
+++ b/src/udev/keymap/95-keyboard-force-release.rules
@@ -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*", RUN+="keyboard-force-release.sh $devpath samsung-90x3a"
+
+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
index 0000000000..506310ef70
--- /dev/null
+++ b/src/udev/keymap/95-keymap.rules
@@ -0,0 +1,175 @@
+# 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}=="*90X3A*", RUN+="keymap $name samsung-90x3a"
+
+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
index 0000000000..2cf2a4e88c
--- /dev/null
+++ b/src/udev/keymap/README.keymap.txt
@@ -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
index 0000000000..c4572745e0
--- /dev/null
+++ b/src/udev/keymap/check-keymaps.sh
@@ -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
index 0000000000..9ce27429b2
--- /dev/null
+++ b/src/udev/keymap/findkeyboards
@@ -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
index 0000000000..b82674840f
--- /dev/null
+++ b/src/udev/keymap/keyboard-force-release.sh.in
@@ -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
index 0000000000..939407fd0b
--- /dev/null
+++ b/src/udev/keymap/keymap.c
@@ -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.
+ *
+ * keymap 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.
+ *
+ * keymap is distributed in the hope that 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 keymap; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
index 0000000000..70c04db40b
--- /dev/null
+++ b/src/udev/mtd_probe/mtd_probe.c
@@ -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
index 0000000000..2a37ede578
--- /dev/null
+++ b/src/udev/mtd_probe/mtd_probe.h
@@ -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
index 0000000000..feadb5076c
--- /dev/null
+++ b/src/udev/mtd_probe/probe_smartmedia.c
@@ -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
index 0000000000..6aebddd809
--- /dev/null
+++ b/src/udev/scsi_id/.gitignore
@@ -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
index 0000000000..9cfe73991c
--- /dev/null
+++ b/src/udev/scsi_id/README
@@ -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
index 0000000000..c423cac574
--- /dev/null
+++ b/src/udev/scsi_id/scsi.h
@@ -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
index 0000000000..c90b6aa581
--- /dev/null
+++ b/src/udev/scsi_id/scsi_id.c
@@ -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
index 0000000000..828a98305f
--- /dev/null
+++ b/src/udev/scsi_id/scsi_id.h
@@ -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
index 0000000000..3c52dee62d
--- /dev/null
+++ b/src/udev/scsi_id/scsi_serial.c
@@ -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
index 0000000000..4293103046
--- /dev/null
+++ b/src/udev/udev-builtin-blkid.c
@@ -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
index 0000000000..dfb05525ad
--- /dev/null
+++ b/src/udev/udev-builtin-btrfs.c
@@ -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
index 0000000000..2fb75a7335
--- /dev/null
+++ b/src/udev/udev-builtin-firmware.c
@@ -0,0 +1,172 @@
+/*
+ * 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) {
+ 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
index 0000000000..234448cdf1
--- /dev/null
+++ b/src/udev/udev-builtin-hwdb.c
@@ -0,0 +1,159 @@
+/***
+ 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;
+
+ 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
index 0000000000..445b602f9c
--- /dev/null
+++ b/src/udev/udev-builtin-input_id.c
@@ -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
index 0000000000..17aca2944d
--- /dev/null
+++ b/src/udev/udev-builtin-kmod.c
@@ -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
index 0000000000..eff4552778
--- /dev/null
+++ b/src/udev/udev-builtin-net_id.c
@@ -0,0 +1,55 @@
+/***
+ 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 <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "udev.h"
+
+/* IEEE Organizationally Unique Identifier */
+static int lookup_OUI(struct udev_device *dev, bool test) {
+ const char *addr;
+ unsigned int a1, a2, a3;
+ char oui[16];
+
+ addr = udev_device_get_sysattr_value(dev, "address");
+ if (!addr)
+ return -ENOENT;
+
+ if (sscanf(addr, "%x:%x:%x:", &a1, &a2, &a3) != 3)
+ return -EINVAL;
+
+ snprintf(oui, sizeof(oui), "OUI:%X%X%X", a1, a2, a3);
+ return udev_builtin_hwdb_lookup(dev, oui, test);
+}
+
+static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
+ lookup_OUI(dev, test);
+ 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
index 0000000000..bfdedc0989
--- /dev/null
+++ b/src/udev/udev-builtin-path_id.c
@@ -0,0 +1,549 @@
+/*
+ * 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(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;
+ }
+
+ 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
index 0000000000..662bac9e0b
--- /dev/null
+++ b/src/udev/udev-builtin-uaccess.c
@@ -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
index 0000000000..13d1226393
--- /dev/null
+++ b/src/udev/udev-builtin-usb_id.c
@@ -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
index 0000000000..ee81b2d713
--- /dev/null
+++ b/src/udev/udev-builtin.c
@@ -0,0 +1,144 @@
+/***
+ 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[] = {
+ [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
+ [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,
+ [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
+ [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
index 0000000000..a235912ffb
--- /dev/null
+++ b/src/udev/udev-ctrl.c
@@ -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
index 0000000000..33ed477637
--- /dev/null
+++ b/src/udev/udev-event.c
@@ -0,0 +1,905 @@
+/*
+ * 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->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
index 0000000000..7774303704
--- /dev/null
+++ b/src/udev/udev-node.c
@@ -0,0 +1,342 @@
+/*
+ * 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;
+ }
+
+ 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);
+ }
+
+ /*
+ * Set initial selinux file context only on add events.
+ * We set the proper context on bootup (triger) or for newly
+ * added devices, but we don't change it later, in case
+ * something else has set a custom context in the meantime.
+ */
+ if (strcmp(udev_device_get_action(dev), "add") == 0)
+ 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
index 0000000000..e6f0f5da7e
--- /dev/null
+++ b/src/udev/udev-rules.c
@@ -0,0 +1,2573 @@
+/*
+ * 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->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->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->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->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
index 0000000000..311f5bdf23
--- /dev/null
+++ b/src/udev/udev-watch.c
@@ -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
index 0000000000..f39253eb67
--- /dev/null
+++ b/src/udev/udev.conf
@@ -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
index 0000000000..82cd2ad6d0
--- /dev/null
+++ b/src/udev/udev.h
@@ -0,0 +1,201 @@
+/*
+ * 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_final;
+ 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 {
+ UDEV_BUILTIN_BLKID,
+ UDEV_BUILTIN_BTRFS,
+ UDEV_BUILTIN_FIRMWARE,
+ UDEV_BUILTIN_HWDB,
+ UDEV_BUILTIN_INPUT_ID,
+ UDEV_BUILTIN_KMOD,
+ 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;
+};
+extern const struct udev_builtin udev_builtin_blkid;
+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;
+extern const struct udev_builtin udev_builtin_kmod;
+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
index 0000000000..a0c2e82d47
--- /dev/null
+++ b/src/udev/udev.pc.in
@@ -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
index 0000000000..c5a189257d
--- /dev/null
+++ b/src/udev/udevadm-control.c
@@ -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
index 0000000000..02d8d01f8a
--- /dev/null
+++ b/src/udev/udevadm-hwdb.c
@@ -0,0 +1,601 @@
+/***
+ 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 [--create] [--help]\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("/etc/udev/hwdb.bin", 0755);
+ err = trie_store(trie, "/etc/udev/hwdb.bin");
+ if (err < 0) {
+ log_error("Failure writing hardware database '%s': %s", "/etc/udev/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
index 0000000000..95f077ca95
--- /dev/null
+++ b/src/udev/udevadm-info.c
@@ -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
index 0000000000..ffa70d8300
--- /dev/null
+++ b/src/udev/udevadm-monitor.c
@@ -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
index 0000000000..c4fc4ee4e5
--- /dev/null
+++ b/src/udev/udevadm-settle.c
@@ -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
index 0000000000..9853d83b49
--- /dev/null
+++ b/src/udev/udevadm-test-builtin.c
@@ -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
index 0000000000..2d8aa7913e
--- /dev/null
+++ b/src/udev/udevadm-test.c
@@ -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
index 0000000000..d52ae461fe
--- /dev/null
+++ b/src/udev/udevadm-trigger.c
@@ -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
index 0000000000..53419ffa62
--- /dev/null
+++ b/src/udev/udevadm.c
@@ -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
index 0000000000..ebd601e262
--- /dev/null
+++ b/src/udev/udevd.c
@@ -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:deDtN: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
index 0000000000..8dcb645ed9
--- /dev/null
+++ b/src/udev/v4l_id/v4l_id.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/update-utmp/Makefile
@@ -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
index 0000000000..a311280c27
--- /dev/null
+++ b/src/update-utmp/update-utmp.c
@@ -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
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/vconsole/Makefile
@@ -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
index 0000000000..ca208497c3
--- /dev/null
+++ b/src/vconsole/vconsole-setup.c
@@ -0,0 +1,392 @@
+/*-*- 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;
+#ifdef TARGET_GENTOO
+ char *vc_unicode = NULL;
+#endif
+#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
+ char *vc_keytable = NULL;
+#endif
+ 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) {
+#if defined(TARGET_SUSE)
+ r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
+ "KEYTABLE", &vc_keymap,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r));
+
+ r = parse_env_file("/etc/sysconfig/console", NEWLINE,
+ "CONSOLE_FONT", &vc_font,
+ "CONSOLE_SCREENMAP", &vc_font_map,
+ "CONSOLE_UNICODEMAP", &vc_font_unimap,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r));
+
+#elif defined(TARGET_ALTLINUX)
+ r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
+ "KEYTABLE", &vc_keymap,
+ NULL)
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r));
+
+ r = parse_env_file("/etc/sysconfig/consolefont", NEWLINE,
+ "SYSFONT", &vc_font,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/consolefont: %s", strerror(-r));
+
+#elif defined(TARGET_GENTOO)
+ r = parse_env_file("/etc/rc.conf", NEWLINE,
+ "unicode", &vc_unicode,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/rc.conf: %s", strerror(-r));
+
+ if (vc_unicode) {
+ int rc_unicode;
+
+ rc_unicode = parse_boolean(vc_unicode);
+ if (rc_unicode < 0)
+ log_warning("Unknown value for /etc/rc.conf unicode=%s", vc_unicode);
+ else {
+ if (rc_unicode && !utf8)
+ log_warning("/etc/rc.conf wants unicode, but current locale is not UTF-8 capable!");
+ else if (!rc_unicode && utf8) {
+ log_debug("/etc/rc.conf does not want unicode, leave it on in kernel but does not apply to vconsole.");
+ utf8 = false;
+ }
+ }
+ }
+
+ /* /etc/conf.d/consolefont comments and gentoo
+ * documentation mention uppercase, but the actual
+ * contents are lowercase. the existing
+ * /etc/init.d/consolefont tries both
+ */
+ r = parse_env_file("/etc/conf.d/consolefont", NEWLINE,
+ "CONSOLEFONT", &vc_font,
+ "consolefont", &vc_font,
+ "consoletranslation", &vc_font_map,
+ "CONSOLETRANSLATION", &vc_font_map,
+ "unicodemap", &vc_font_unimap,
+ "UNICODEMAP", &vc_font_unimap,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/conf.d/consolefont: %s", strerror(-r));
+
+ r = parse_env_file("/etc/conf.d/keymaps", NEWLINE,
+ "keymap", &vc_keymap,
+ "KEYMAP", &vc_keymap,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/conf.d/keymaps: %s", strerror(-r));
+
+#elif defined(TARGET_MANDRIVA) || defined (TARGET_MAGEIA)
+
+ r = parse_env_file("/etc/sysconfig/i18n", NEWLINE,
+ "SYSFONT", &vc_font,
+ "SYSFONTACM", &vc_font_map,
+ "UNIMAP", &vc_font_unimap,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r));
+
+ r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE,
+ "KEYTABLE", &vc_keytable,
+ "KEYMAP", &vc_keymap,
+ "UNIKEYTABLE", &vc_keymap,
+ "GRP_TOGGLE", &vc_keymap_toggle,
+ NULL);
+ if (r < 0 && r != -ENOENT)
+ log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r));
+
+ if (vc_keytable) {
+ free(vc_keymap);
+ if (utf8) {
+ if (endswith(vc_keytable, ".uni") || strstr(vc_keytable, ".uni."))
+ vc_keymap = strdup(vc_keytable);
+ else {
+ char *s;
+ s = strstr(vc_keytable, ".map");
+ if (s)
+ vc_keytable[s-vc_keytable+1] = '\0';
+ vc_keymap = strappend(vc_keytable, ".uni");
+ }
+ } else
+ vc_keymap = strdup(vc_keytable);
+
+ free(vc_keytable);
+
+ if (!vc_keymap) {
+ log_oom();
+ goto finish;
+ }
+ }
+
+ if (access("/etc/sysconfig/console/default.kmap", F_OK) >= 0) {
+ char *t;
+
+ t = strdup("/etc/sysconfig/console/default.kmap");
+ if (!t) {
+ log_oom();
+ goto finish;
+ }
+
+ free(vc_keymap);
+ vc_keymap = t;
+ }
+#endif
+ }
+
+ 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
index 0000000000..7563539ab0
--- /dev/null
+++ b/sysctl.d/.gitignore
@@ -0,0 +1 @@
+/coredump.conf
diff --git a/sysctl.d/Makefile b/sysctl.d/Makefile
new file mode 120000
index 0000000000..bd1047548b
--- /dev/null
+++ b/sysctl.d/Makefile
@@ -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
index 0000000000..5c791b791b
--- /dev/null
+++ b/sysctl.d/coredump.conf.in
@@ -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
index 0000000000..93c1f950fe
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,3 @@
+.testdir
+test.log
+/sys
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000000..987a32548f
--- /dev/null
+++ b/test/Makefile
@@ -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
index 0000000000..0f96b984a9
--- /dev/null
+++ b/test/README.testsuite
@@ -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
index 0000000000..5e89a29eff
--- /dev/null
+++ b/test/TEST-01-BASIC/Makefile
@@ -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
index 0000000000..eb6a80a07c
--- /dev/null
+++ b/test/TEST-01-BASIC/test.sh
@@ -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
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-02-CRYPTSETUP/Makefile
@@ -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
index 0000000000..790dc3074c
--- /dev/null
+++ b/test/TEST-02-CRYPTSETUP/test.sh
@@ -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
index 0000000000..4168d2d051
--- /dev/null
+++ b/test/a.service
@@ -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
index 0000000000..e03bae36be
--- /dev/null
+++ b/test/b.service
@@ -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
index 0000000000..e2f60a8fbf
--- /dev/null
+++ b/test/c.service
@@ -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
index 0000000000..921fd2ee1b
--- /dev/null
+++ b/test/d.service
@@ -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
index 0000000000..5ba98c7c43
--- /dev/null
+++ b/test/e.service
@@ -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
index 0000000000..7dde681c17
--- /dev/null
+++ b/test/f.service
@@ -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
index 0000000000..cbfa82a454
--- /dev/null
+++ b/test/g.service
@@ -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
index 0000000000..74a7751cad
--- /dev/null
+++ b/test/h.service
@@ -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
index 0000000000..4b602a925a
--- /dev/null
+++ b/test/rule-syntax-check.py
@@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
index 0000000000..1e224ff8b5
--- /dev/null
+++ b/test/rules-test.sh
@@ -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/sys.tar.xz b/test/sys.tar.xz
new file mode 100644
index 0000000000..49ee8027b2
--- /dev/null
+++ b/test/sys.tar.xz
Binary files differ
diff --git a/test/test-functions b/test/test-functions
new file mode 100644
index 0000000000..0587cd4feb
--- /dev/null
+++ b/test/test-functions
@@ -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
index 0000000000..a9f5db03cf
--- /dev/null
+++ b/test/udev-test.pl
@@ -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
index 0000000000..bd1047548b
--- /dev/null
+++ b/tmpfiles.d/Makefile
@@ -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
index 0000000000..92bd71b98c
--- /dev/null
+++ b/tmpfiles.d/legacy.conf
@@ -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
index 0000000000..965c6fc322
--- /dev/null
+++ b/tmpfiles.d/systemd.conf
@@ -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
index 0000000000..1284fc4700
--- /dev/null
+++ b/tmpfiles.d/tmp.conf
@@ -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
index 0000000000..ece6a5ce98
--- /dev/null
+++ b/tmpfiles.d/x11.conf
@@ -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
index 0000000000..63c7ba06bb
--- /dev/null
+++ b/units/.gitignore
@@ -0,0 +1,49 @@
+/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
index 0000000000..bd1047548b
--- /dev/null
+++ b/units/Makefile
@@ -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
index 0000000000..f9d03fa16f
--- /dev/null
+++ b/units/basic.target
@@ -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
index 0000000000..dd4ae14cfb
--- /dev/null
+++ b/units/bluetooth.target
@@ -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
index 0000000000..9d80d4b6f6
--- /dev/null
+++ b/units/console-getty.service.m4.in
@@ -0,0 +1,49 @@
+# 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(`TARGET_FEDORA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_ARCH',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_FRUGALWARE',
+After=local.service
+)m4_dnl
+m4_ifdef(`TARGET_ALTLINUX',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MANDRIVA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+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
index 0000000000..e0fbc61b96
--- /dev/null
+++ b/units/console-shell.service.m4.in
@@ -0,0 +1,52 @@
+# 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(`TARGET_FEDORA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_DEBIAN',
+After=rc.local.service
+)m4_dnl
+m4_ifdef(`TARGET_ARCH',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_FRUGALWARE',
+After=local.service
+)m4_dnl
+m4_ifdef(`TARGET_ALTLINUX',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MANDRIVA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+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
index 0000000000..25d3e33f6a
--- /dev/null
+++ b/units/cryptsetup.target
@@ -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
index 0000000000..2aa98d3cc5
--- /dev/null
+++ b/units/debug-shell.service.in
@@ -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
index 0000000000..9381167c83
--- /dev/null
+++ b/units/dev-hugepages.mount
@@ -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
index 0000000000..5786bb1519
--- /dev/null
+++ b/units/dev-mqueue.mount
@@ -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
index 0000000000..129a83150a
--- /dev/null
+++ b/units/emergency.service.in
@@ -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 -b" 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
index 0000000000..0760d66f95
--- /dev/null
+++ b/units/emergency.target
@@ -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/fedora/Makefile b/units/fedora/Makefile
new file mode 120000
index 0000000000..50be21181f
--- /dev/null
+++ b/units/fedora/Makefile
@@ -0,0 +1 @@
+../../src/Makefile \ No newline at end of file
diff --git a/units/fedora/halt-local.service b/units/fedora/halt-local.service
new file mode 100644
index 0000000000..a0a3a292e7
--- /dev/null
+++ b/units/fedora/halt-local.service
@@ -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=/sbin/halt.local Compatibility
+ConditionFileIsExecutable=/sbin/halt.local
+DefaultDependencies=no
+After=shutdown.target
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=/sbin/halt.local
+TimeoutSec=0
+StandardOutput=tty
+RemainAfterExit=yes
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
new file mode 100644
index 0000000000..3b3bda9f6f
--- /dev/null
+++ b/units/fedora/rc-local.service
@@ -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 unit gets pulled automatically into multi-user.target by
+# systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
+[Unit]
+Description=/etc/rc.d/rc.local Compatibility
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/etc/rc.d/rc.local start
+TimeoutSec=0
+RemainAfterExit=yes
+SysVStartPriority=99
diff --git a/units/final.target b/units/final.target
new file mode 100644
index 0000000000..42819105c8
--- /dev/null
+++ b/units/final.target
@@ -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/frugalware/display-manager.service b/units/frugalware/display-manager.service
new file mode 100644
index 0000000000..a5c475cd9e
--- /dev/null
+++ b/units/frugalware/display-manager.service
@@ -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=Display Manager
+After=local.service systemd-user-sessions.service
+
+[Service]
+EnvironmentFile=/etc/sysconfig/desktop
+ExecStart=/bin/bash -c "exec ${desktop}"
+Restart=always
+RestartSec=0
diff --git a/units/getty.target b/units/getty.target
new file mode 100644
index 0000000000..d53da35f9c
--- /dev/null
+++ b/units/getty.target
@@ -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=Login Prompts
+Documentation=man:systemd.special(7)
diff --git a/units/getty@.service.m4 b/units/getty@.service.m4
new file mode 100644
index 0000000000..810c23fc12
--- /dev/null
+++ b/units/getty@.service.m4
@@ -0,0 +1,68 @@
+# 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)
+After=systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`TARGET_FEDORA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_DEBIAN',
+After=rc.local.service
+)m4_dnl
+m4_ifdef(`TARGET_ARCH',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_FRUGALWARE',
+After=local.service
+)m4_dnl
+m4_ifdef(`TARGET_ALTLINUX',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MANDRIVA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+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
index 0000000000..65f2521d9e
--- /dev/null
+++ b/units/graphical.target
@@ -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.target b/units/halt.target
new file mode 100644
index 0000000000..a21d984b26
--- /dev/null
+++ b/units/halt.target
@@ -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
index 0000000000..143eb59230
--- /dev/null
+++ b/units/hibernate.target
@@ -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
index 0000000000..d2d3409225
--- /dev/null
+++ b/units/hybrid-sleep.target
@@ -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
index 0000000000..90795d0c5a
--- /dev/null
+++ b/units/kexec.target
@@ -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
index 0000000000..f8760ec9df
--- /dev/null
+++ b/units/local-fs-pre.target
@@ -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
index 0000000000..dd92b17b6a
--- /dev/null
+++ b/units/local-fs.target
@@ -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
index 0000000000..d2f24d15b9
--- /dev/null
+++ b/units/mail-transfer-agent.target
@@ -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
index 0000000000..6e3f0b4f7a
--- /dev/null
+++ b/units/multi-user.target
@@ -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
index 0000000000..5406f4e5d9
--- /dev/null
+++ b/units/network.target
@@ -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
index 0000000000..eea905a715
--- /dev/null
+++ b/units/nss-lookup.target
@@ -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
index 0000000000..3e0fced101
--- /dev/null
+++ b/units/nss-user-lookup.target
@@ -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
index 0000000000..71871033a5
--- /dev/null
+++ b/units/poweroff.target
@@ -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
index 0000000000..a6b86caa8d
--- /dev/null
+++ b/units/printer.target
@@ -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
index 0000000000..7fd5afe3cd
--- /dev/null
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -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
index 0000000000..c64c84951e
--- /dev/null
+++ b/units/proc-sys-fs-binfmt_misc.mount
@@ -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
index 0000000000..49a50a7feb
--- /dev/null
+++ b/units/quotaon.service.in
@@ -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/reboot.target b/units/reboot.target
new file mode 100644
index 0000000000..dec8f56796
--- /dev/null
+++ b/units/reboot.target
@@ -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
index 0000000000..2169533bd3
--- /dev/null
+++ b/units/remote-fs-pre.target
@@ -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
index 0000000000..9e68878ad8
--- /dev/null
+++ b/units/remote-fs.target
@@ -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
index 0000000000..89059e05de
--- /dev/null
+++ b/units/rescue.service.m4.in
@@ -0,0 +1,40 @@
+# 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 -b" to view system logs. Type "systemctl reboot" to reboot.'
+m4_ifdef(`TARGET_FEDORA',
+`EnvironmentFile=/etc/sysconfig/init
+ExecStart=-/bin/bash -c "exec ${SINGLE}"',
+m4_ifdef(`TARGET_MANDRIVA',
+`EnvironmentFile=/etc/sysconfig/init
+ExecStart=-/bin/bash -c "exec ${SINGLE}"',
+m4_ifdef(`TARGET_MAGEIA',
+`EnvironmentFile=/etc/sysconfig/init
+ExecStart=-/bin/bash -c "exec ${SINGLE}"',
+`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
index 0000000000..3f59b14339
--- /dev/null
+++ b/units/rescue.target
@@ -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
index 0000000000..eb06a6db26
--- /dev/null
+++ b/units/rpcbind.target
@@ -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
index 0000000000..c411dc1121
--- /dev/null
+++ b/units/serial-getty@.service.m4
@@ -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.
+
+[Unit]
+Description=Serial Getty on %I
+Documentation=man:agetty(8) man:systemd-getty-generator(8)
+BindsTo=dev-%i.device
+After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
+m4_ifdef(`TARGET_FEDORA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_DEBIAN',
+After=rc.local.service
+)m4_dnl
+m4_ifdef(`TARGET_ARCH',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_FRUGALWARE',
+After=local.service
+)m4_dnl
+m4_ifdef(`TARGET_ALTLINUX',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MANDRIVA',
+After=rc-local.service
+)m4_dnl
+m4_ifdef(`TARGET_MAGEIA',
+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
index 0000000000..73e302b8b2
--- /dev/null
+++ b/units/shutdown.target
@@ -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
index 0000000000..a52e7cffc9
--- /dev/null
+++ b/units/sigpwr.target
@@ -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
index 0000000000..10c7c8d594
--- /dev/null
+++ b/units/sleep.target
@@ -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
index 0000000000..5fefe84703
--- /dev/null
+++ b/units/smartcard.target
@@ -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
index 0000000000..26ab065d02
--- /dev/null
+++ b/units/sockets.target
@@ -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
index 0000000000..6699adeceb
--- /dev/null
+++ b/units/sound.target
@@ -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/suse/halt-local.service b/units/suse/halt-local.service
new file mode 100644
index 0000000000..3a3a7930e2
--- /dev/null
+++ b/units/suse/halt-local.service
@@ -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=/etc/init.d/halt.local Compatibility
+ConditionFileIsExecutable=/etc/init.d/halt.local
+DefaultDependencies=no
+After=shutdown.target
+Before=final.target
+
+[Service]
+Type=oneshot
+ExecStart=/etc/init.d/halt.local
+TimeoutSec=0
+StandardOutput=tty
+RemainAfterExit=yes
diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
new file mode 100644
index 0000000000..0fd70e0fc9
--- /dev/null
+++ b/units/suse/rc-local.service
@@ -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 unit gets pulled automatically into multi-user.target by
+# systemd-rc-local-generator if /etc/init.d/boot.local is executable.
+[Unit]
+Description=/etc/init.d/boot.local Compatibility
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=/etc/init.d/boot.local
+TimeoutSec=0
+RemainAfterExit=yes
+SysVStartPriority=99
diff --git a/units/suspend.target b/units/suspend.target
new file mode 100644
index 0000000000..f50cb2264f
--- /dev/null
+++ b/units/suspend.target
@@ -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
index 0000000000..23a7d0dc9c
--- /dev/null
+++ b/units/swap.target
@@ -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
index 0000000000..9269ea4272
--- /dev/null
+++ b/units/sys-fs-fuse-connections.mount
@@ -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
index 0000000000..e7cd4909c1
--- /dev/null
+++ b/units/sys-kernel-config.mount
@@ -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
index 0000000000..8b1e33e7f7
--- /dev/null
+++ b/units/sys-kernel-debug.mount
@@ -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
index 0000000000..8f4fb8f5c1
--- /dev/null
+++ b/units/sysinit.target
@@ -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
index 0000000000..c784357627
--- /dev/null
+++ b/units/syslog.socket
@@ -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
index 0000000000..423fef30ad
--- /dev/null
+++ b/units/syslog.target
@@ -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
index 0000000000..d0f847f957
--- /dev/null
+++ b/units/system-update.target
@@ -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
index 0000000000..80f6cc4c18
--- /dev/null
+++ b/units/systemd-ask-password-console.path
@@ -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
index 0000000000..4bcb30be02
--- /dev/null
+++ b/units/systemd-ask-password-console.service.in
@@ -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
index 0000000000..62dee80552
--- /dev/null
+++ b/units/systemd-ask-password-wall.path
@@ -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
index 0000000000..0eaa274794
--- /dev/null
+++ b/units/systemd-ask-password-wall.service.in
@@ -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
index 0000000000..02dfe774df
--- /dev/null
+++ b/units/systemd-binfmt.service.in
@@ -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
index 0000000000..ef5123feb8
--- /dev/null
+++ b/units/systemd-fsck-root.service.in
@@ -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
index 0000000000..b3c71eb250
--- /dev/null
+++ b/units/systemd-fsck@.service.in
@@ -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
index 0000000000..d55d622c1c
--- /dev/null
+++ b/units/systemd-halt.service.in
@@ -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
index 0000000000..29d9b696a8
--- /dev/null
+++ b/units/systemd-hibernate.service.in
@@ -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
index 0000000000..be22a3ad01
--- /dev/null
+++ b/units/systemd-hostnamed.service.in
@@ -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
diff --git a/units/systemd-hybrid-sleep.service.in b/units/systemd-hybrid-sleep.service.in
new file mode 100644
index 0000000000..914b686c36
--- /dev/null
+++ b/units/systemd-hybrid-sleep.service.in
@@ -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
index 0000000000..27e663c8dc
--- /dev/null
+++ b/units/systemd-initctl.service.in
@@ -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
index 0000000000..b98d5ca6e9
--- /dev/null
+++ b/units/systemd-initctl.socket
@@ -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
index 0000000000..503e8a63b8
--- /dev/null
+++ b/units/systemd-journal-flush.service.in
@@ -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
index 0000000000..c3b5c725bf
--- /dev/null
+++ b/units/systemd-journal-gatewayd.service.in
@@ -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
index 0000000000..fd11058ab4
--- /dev/null
+++ b/units/systemd-journal-gatewayd.socket
@@ -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
index 0000000000..ab2e50c22c
--- /dev/null
+++ b/units/systemd-journald.service.in
@@ -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
index 0000000000..dbe8882c0e
--- /dev/null
+++ b/units/systemd-journald.socket
@@ -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
index 0000000000..61303f917f
--- /dev/null
+++ b/units/systemd-kexec.service.in
@@ -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
index 0000000000..6818a4c5c6
--- /dev/null
+++ b/units/systemd-localed.service.in
@@ -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
index 0000000000..cf3c430b7f
--- /dev/null
+++ b/units/systemd-logind.service.in
@@ -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
index 0000000000..32deb52e26
--- /dev/null
+++ b/units/systemd-modules-load.service.in
@@ -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
index 0000000000..3630719733
--- /dev/null
+++ b/units/systemd-poweroff.service.in
@@ -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
index 0000000000..f726ea1bcd
--- /dev/null
+++ b/units/systemd-quotacheck.service.in
@@ -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
index 0000000000..e9156ef086
--- /dev/null
+++ b/units/systemd-random-seed-load.service.in
@@ -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
index 0000000000..3444d4ce70
--- /dev/null
+++ b/units/systemd-random-seed-save.service.in
@@ -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
index 0000000000..d4b8e67932
--- /dev/null
+++ b/units/systemd-readahead-collect.service.in
@@ -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
index 0000000000..c3b2ac506a
--- /dev/null
+++ b/units/systemd-readahead-done.service.in
@@ -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
index 0000000000..2828d198a6
--- /dev/null
+++ b/units/systemd-readahead-done.timer
@@ -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
index 0000000000..d9d12bc533
--- /dev/null
+++ b/units/systemd-readahead-drop.service
@@ -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
index 0000000000..c64a533e4e
--- /dev/null
+++ b/units/systemd-readahead-replay.service.in
@@ -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
index 0000000000..d99bd3e701
--- /dev/null
+++ b/units/systemd-reboot.service.in
@@ -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
index 0000000000..cddb0a1fb9
--- /dev/null
+++ b/units/systemd-remount-fs.service.in
@@ -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
index 0000000000..d951742500
--- /dev/null
+++ b/units/systemd-shutdownd.service.in
@@ -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
index 0000000000..9421ce8ada
--- /dev/null
+++ b/units/systemd-shutdownd.socket
@@ -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
index 0000000000..3a702d2e22
--- /dev/null
+++ b/units/systemd-suspend.service.in
@@ -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
index 0000000000..45e1ceb25c
--- /dev/null
+++ b/units/systemd-sysctl.service.in
@@ -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
index 0000000000..dd3eb1b337
--- /dev/null
+++ b/units/systemd-timedated.service.in
@@ -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
index 0000000000..a288232e12
--- /dev/null
+++ b/units/systemd-tmpfiles-clean.service.in
@@ -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
index 0000000000..fac4ee3da8
--- /dev/null
+++ b/units/systemd-tmpfiles-clean.timer
@@ -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
index 0000000000..dbd6bfb6d5
--- /dev/null
+++ b/units/systemd-tmpfiles-setup.service.in
@@ -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
index 0000000000..b631949648
--- /dev/null
+++ b/units/systemd-udev-settle.service.in
@@ -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
index 0000000000..391f996930
--- /dev/null
+++ b/units/systemd-udev-trigger.service.in
@@ -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
index 0000000000..9065ea2c64
--- /dev/null
+++ b/units/systemd-udevd-control.socket
@@ -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
index 0000000000..54a005b7a7
--- /dev/null
+++ b/units/systemd-udevd-kernel.socket
@@ -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
index 0000000000..2fe7822fe9
--- /dev/null
+++ b/units/systemd-udevd.service.in
@@ -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
index 0000000000..27fae2cd02
--- /dev/null
+++ b/units/systemd-update-utmp-runlevel.service.in
@@ -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
index 0000000000..aa93562f02
--- /dev/null
+++ b/units/systemd-update-utmp-shutdown.service.in
@@ -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
index 0000000000..0869e73991
--- /dev/null
+++ b/units/systemd-user-sessions.service.in
@@ -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
index 0000000000..18faa63f28
--- /dev/null
+++ b/units/systemd-vconsole-setup.service.in
@@ -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
index 0000000000..ec00ecbbf4
--- /dev/null
+++ b/units/time-sync.target
@@ -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
index 0000000000..94c41c29ba
--- /dev/null
+++ b/units/tmp.mount
@@ -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
index 0000000000..39668d85d2
--- /dev/null
+++ b/units/umount.target
@@ -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
index 0000000000..41a74f5461
--- /dev/null
+++ b/units/user/.gitignore
@@ -0,0 +1 @@
+/systemd-exit.service
diff --git a/units/user/Makefile b/units/user/Makefile
new file mode 120000
index 0000000000..50be21181f
--- /dev/null
+++ b/units/user/Makefile
@@ -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
index 0000000000..56cf4dcb9c
--- /dev/null
+++ b/units/user/default.target
@@ -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
index 0000000000..b0ad24c488
--- /dev/null
+++ b/units/user/exit.target
@@ -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
index 0000000000..987fab8120
--- /dev/null
+++ b/units/user/systemd-exit.service.in
@@ -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
index 0000000000..2c154953b1
--- /dev/null
+++ b/units/user@.service.in
@@ -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