From 6997e3b2dc0095985071e2f7496342a850cdb5ad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 7 Mar 2012 16:46:55 +0100 Subject: move src/extras subdirectories to src/ --- Makefile.am | 418 ++++---- configure.ac | 4 +- rules/misc/30-kernel-compat.rules | 2 +- src/accelerometer/.gitignore | 1 + src/accelerometer/61-accelerometer.rules | 3 + src/accelerometer/accelerometer.c | 357 +++++++ src/ata_id/.gitignore | 1 + src/ata_id/ata_id.c | 726 +++++++++++++ src/cdrom_id/.gitignore | 1 + src/cdrom_id/60-cdrom_id.rules | 20 + src/cdrom_id/cdrom_id.c | 1099 ++++++++++++++++++++ src/collect/.gitignore | 1 + src/collect/collect.c | 473 +++++++++ src/edd_id/.gitignore | 1 + src/edd_id/61-persistent-storage-edd.rules | 12 + src/edd_id/edd_id.c | 196 ++++ src/extras/accelerometer/.gitignore | 1 - src/extras/accelerometer/61-accelerometer.rules | 3 - src/extras/accelerometer/accelerometer.c | 357 ------- src/extras/ata_id/.gitignore | 1 - src/extras/ata_id/ata_id.c | 726 ------------- src/extras/cdrom_id/.gitignore | 1 - src/extras/cdrom_id/60-cdrom_id.rules | 20 - src/extras/cdrom_id/cdrom_id.c | 1099 -------------------- src/extras/collect/.gitignore | 1 - src/extras/collect/collect.c | 473 --------- src/extras/edd_id/.gitignore | 1 - src/extras/edd_id/61-persistent-storage-edd.rules | 12 - src/extras/edd_id/edd_id.c | 196 ---- src/extras/floppy/.gitignore | 1 - src/extras/floppy/60-floppy.rules | 4 - src/extras/floppy/create_floppy_devices.c | 177 ---- src/extras/gudev/.gitignore | 9 - src/extras/gudev/COPYING | 502 --------- src/extras/gudev/docs/.gitignore | 16 - src/extras/gudev/docs/Makefile.am | 106 -- src/extras/gudev/docs/gudev-docs.xml | 93 -- src/extras/gudev/docs/gudev-sections.txt | 113 -- src/extras/gudev/docs/gudev.types | 4 - src/extras/gudev/docs/version.xml.in | 1 - src/extras/gudev/gjs-example.js | 75 -- src/extras/gudev/gudev-1.0.pc.in | 11 - src/extras/gudev/gudev.h | 33 - src/extras/gudev/gudevclient.c | 527 ---------- src/extras/gudev/gudevclient.h | 100 -- src/extras/gudev/gudevdevice.c | 963 ----------------- src/extras/gudev/gudevdevice.h | 128 --- src/extras/gudev/gudevenumerator.c | 431 -------- src/extras/gudev/gudevenumerator.h | 107 -- src/extras/gudev/gudevenums.h | 49 - src/extras/gudev/gudevenumtypes.c.template | 39 - src/extras/gudev/gudevenumtypes.h.template | 24 - src/extras/gudev/gudevmarshal.list | 1 - src/extras/gudev/gudevprivate.h | 41 - src/extras/gudev/gudevtypes.h | 51 - src/extras/gudev/seed-example-enum.js | 38 - src/extras/gudev/seed-example.js | 72 -- src/extras/keymap/.gitignore | 6 - src/extras/keymap/95-keyboard-force-release.rules | 53 - src/extras/keymap/95-keymap.rules | 169 --- src/extras/keymap/README.keymap.txt | 101 -- src/extras/keymap/check-keymaps.sh | 38 - src/extras/keymap/findkeyboards | 68 -- .../keymap/force-release-maps/common-volume-keys | 3 - src/extras/keymap/force-release-maps/dell-touchpad | 1 - src/extras/keymap/force-release-maps/hp-other | 3 - src/extras/keymap/force-release-maps/samsung-other | 10 - src/extras/keymap/keyboard-force-release.sh.in | 22 - src/extras/keymap/keymap.c | 447 -------- src/extras/keymap/keymaps/acer | 22 - src/extras/keymap/keymaps/acer-aspire_5720 | 4 - src/extras/keymap/keymaps/acer-aspire_5920g | 5 - src/extras/keymap/keymaps/acer-aspire_6920 | 5 - src/extras/keymap/keymaps/acer-aspire_8930 | 5 - src/extras/keymap/keymaps/acer-travelmate_c300 | 5 - src/extras/keymap/keymaps/asus | 3 - src/extras/keymap/keymaps/compaq-e_evo | 4 - src/extras/keymap/keymaps/dell | 29 - src/extras/keymap/keymaps/dell-latitude-xt2 | 4 - src/extras/keymap/keymaps/everex-xt5000 | 7 - src/extras/keymap/keymaps/fujitsu-amilo_li_2732 | 3 - src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 | 3 - .../keymap/keymaps/fujitsu-amilo_pro_edition_v3505 | 4 - src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 | 2 - src/extras/keymap/keymaps/fujitsu-amilo_si_1520 | 6 - .../keymap/keymaps/fujitsu-esprimo_mobile_v5 | 4 - .../keymap/keymaps/fujitsu-esprimo_mobile_v6 | 2 - src/extras/keymap/keymaps/genius-slimstar-320 | 35 - src/extras/keymap/keymaps/hewlett-packard | 12 - .../keymap/keymaps/hewlett-packard-2510p_2530p | 2 - .../keymaps/hewlett-packard-compaq_elitebook | 2 - src/extras/keymap/keymaps/hewlett-packard-pavilion | 3 - .../keymap/keymaps/hewlett-packard-presario-2100 | 3 - src/extras/keymap/keymaps/hewlett-packard-tablet | 6 - src/extras/keymap/keymaps/hewlett-packard-tx2 | 3 - .../keymaps/ibm-thinkpad-usb-keyboard-trackpoint | 7 - .../keymap/keymaps/inventec-symphony_6.0_7.0 | 2 - src/extras/keymap/keymaps/lenovo-3000 | 5 - src/extras/keymap/keymaps/lenovo-ideapad | 8 - .../lenovo-thinkpad-usb-keyboard-trackpoint | 13 - .../keymap/keymaps/lenovo-thinkpad_x200_tablet | 6 - .../keymap/keymaps/lenovo-thinkpad_x6_tablet | 8 - src/extras/keymap/keymaps/lg-x110 | 12 - src/extras/keymap/keymaps/logitech-wave | 16 - src/extras/keymap/keymaps/logitech-wave-cordless | 15 - .../keymap/keymaps/logitech-wave-pro-cordless | 12 - src/extras/keymap/keymaps/maxdata-pro_7000 | 9 - src/extras/keymap/keymaps/medion-fid2060 | 2 - src/extras/keymap/keymaps/medionnb-a555 | 4 - src/extras/keymap/keymaps/micro-star | 13 - src/extras/keymap/keymaps/module-asus-w3j | 11 - src/extras/keymap/keymaps/module-ibm | 16 - src/extras/keymap/keymaps/module-lenovo | 17 - src/extras/keymap/keymaps/module-sony | 8 - src/extras/keymap/keymaps/module-sony-old | 2 - src/extras/keymap/keymaps/module-sony-vgn | 8 - src/extras/keymap/keymaps/olpc-xo | 74 -- src/extras/keymap/keymaps/onkyo | 14 - src/extras/keymap/keymaps/oqo-model2 | 5 - src/extras/keymap/keymaps/samsung-other | 14 - src/extras/keymap/keymaps/samsung-sq1us | 7 - src/extras/keymap/keymaps/samsung-sx20s | 4 - src/extras/keymap/keymaps/toshiba-satellite_a100 | 2 - src/extras/keymap/keymaps/toshiba-satellite_a110 | 10 - src/extras/keymap/keymaps/toshiba-satellite_m30x | 6 - src/extras/keymap/keymaps/zepto-znote | 11 - src/extras/mtd_probe/.gitignore | 1 - src/extras/mtd_probe/75-probe_mtd.rules | 8 - src/extras/mtd_probe/mtd_probe.c | 51 - src/extras/mtd_probe/mtd_probe.h | 49 - src/extras/mtd_probe/probe_smartmedia.c | 97 -- src/extras/qemu/42-qemu-usb.rules | 13 - .../rule_generator/75-cd-aliases-generator.rules | 9 - .../75-persistent-net-generator.rules | 102 -- src/extras/rule_generator/rule_generator.functions | 113 -- src/extras/rule_generator/write_cd_rules | 126 --- src/extras/rule_generator/write_net_rules | 141 --- src/extras/scsi_id/.gitignore | 3 - src/extras/scsi_id/README | 4 - src/extras/scsi_id/scsi.h | 97 -- src/extras/scsi_id/scsi_id.8 | 119 --- src/extras/scsi_id/scsi_id.c | 657 ------------ src/extras/scsi_id/scsi_id.h | 73 -- src/extras/scsi_id/scsi_serial.c | 990 ------------------ src/extras/v4l_id/.gitignore | 1 - src/extras/v4l_id/60-persistent-v4l.rules | 20 - src/extras/v4l_id/v4l_id.c | 87 -- src/floppy/.gitignore | 1 + src/floppy/60-floppy.rules | 4 + src/floppy/create_floppy_devices.c | 177 ++++ src/gudev/.gitignore | 9 + src/gudev/COPYING | 502 +++++++++ src/gudev/docs/.gitignore | 16 + src/gudev/docs/Makefile.am | 106 ++ src/gudev/docs/gudev-docs.xml | 93 ++ src/gudev/docs/gudev-sections.txt | 113 ++ src/gudev/docs/gudev.types | 4 + src/gudev/docs/version.xml.in | 1 + src/gudev/gjs-example.js | 75 ++ src/gudev/gudev-1.0.pc.in | 11 + src/gudev/gudev.h | 33 + src/gudev/gudevclient.c | 527 ++++++++++ src/gudev/gudevclient.h | 100 ++ src/gudev/gudevdevice.c | 963 +++++++++++++++++ src/gudev/gudevdevice.h | 128 +++ src/gudev/gudevenumerator.c | 431 ++++++++ src/gudev/gudevenumerator.h | 107 ++ src/gudev/gudevenums.h | 49 + src/gudev/gudevenumtypes.c.template | 39 + src/gudev/gudevenumtypes.h.template | 24 + src/gudev/gudevmarshal.list | 1 + src/gudev/gudevprivate.h | 41 + src/gudev/gudevtypes.h | 51 + src/gudev/seed-example-enum.js | 38 + src/gudev/seed-example.js | 72 ++ src/keymap/.gitignore | 6 + src/keymap/95-keyboard-force-release.rules | 53 + src/keymap/95-keymap.rules | 169 +++ src/keymap/README.keymap.txt | 101 ++ src/keymap/check-keymaps.sh | 38 + src/keymap/findkeyboards | 68 ++ src/keymap/force-release-maps/common-volume-keys | 3 + src/keymap/force-release-maps/dell-touchpad | 1 + src/keymap/force-release-maps/hp-other | 3 + src/keymap/force-release-maps/samsung-other | 10 + src/keymap/keyboard-force-release.sh.in | 22 + src/keymap/keymap.c | 447 ++++++++ src/keymap/keymaps/acer | 22 + src/keymap/keymaps/acer-aspire_5720 | 4 + src/keymap/keymaps/acer-aspire_5920g | 5 + src/keymap/keymaps/acer-aspire_6920 | 5 + src/keymap/keymaps/acer-aspire_8930 | 5 + src/keymap/keymaps/acer-travelmate_c300 | 5 + src/keymap/keymaps/asus | 3 + src/keymap/keymaps/compaq-e_evo | 4 + src/keymap/keymaps/dell | 29 + src/keymap/keymaps/dell-latitude-xt2 | 4 + src/keymap/keymaps/everex-xt5000 | 7 + src/keymap/keymaps/fujitsu-amilo_li_2732 | 3 + src/keymap/keymaps/fujitsu-amilo_pa_2548 | 3 + src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 | 4 + src/keymap/keymaps/fujitsu-amilo_pro_v3205 | 2 + src/keymap/keymaps/fujitsu-amilo_si_1520 | 6 + src/keymap/keymaps/fujitsu-esprimo_mobile_v5 | 4 + src/keymap/keymaps/fujitsu-esprimo_mobile_v6 | 2 + src/keymap/keymaps/genius-slimstar-320 | 35 + src/keymap/keymaps/hewlett-packard | 12 + src/keymap/keymaps/hewlett-packard-2510p_2530p | 2 + .../keymaps/hewlett-packard-compaq_elitebook | 2 + src/keymap/keymaps/hewlett-packard-pavilion | 3 + src/keymap/keymaps/hewlett-packard-presario-2100 | 3 + src/keymap/keymaps/hewlett-packard-tablet | 6 + src/keymap/keymaps/hewlett-packard-tx2 | 3 + .../keymaps/ibm-thinkpad-usb-keyboard-trackpoint | 7 + src/keymap/keymaps/inventec-symphony_6.0_7.0 | 2 + src/keymap/keymaps/lenovo-3000 | 5 + src/keymap/keymaps/lenovo-ideapad | 8 + .../lenovo-thinkpad-usb-keyboard-trackpoint | 13 + src/keymap/keymaps/lenovo-thinkpad_x200_tablet | 6 + src/keymap/keymaps/lenovo-thinkpad_x6_tablet | 8 + src/keymap/keymaps/lg-x110 | 12 + src/keymap/keymaps/logitech-wave | 16 + src/keymap/keymaps/logitech-wave-cordless | 15 + src/keymap/keymaps/logitech-wave-pro-cordless | 12 + src/keymap/keymaps/maxdata-pro_7000 | 9 + src/keymap/keymaps/medion-fid2060 | 2 + src/keymap/keymaps/medionnb-a555 | 4 + src/keymap/keymaps/micro-star | 13 + src/keymap/keymaps/module-asus-w3j | 11 + src/keymap/keymaps/module-ibm | 16 + src/keymap/keymaps/module-lenovo | 17 + src/keymap/keymaps/module-sony | 8 + src/keymap/keymaps/module-sony-old | 2 + src/keymap/keymaps/module-sony-vgn | 8 + src/keymap/keymaps/olpc-xo | 74 ++ src/keymap/keymaps/onkyo | 14 + src/keymap/keymaps/oqo-model2 | 5 + src/keymap/keymaps/samsung-other | 14 + src/keymap/keymaps/samsung-sq1us | 7 + src/keymap/keymaps/samsung-sx20s | 4 + src/keymap/keymaps/toshiba-satellite_a100 | 2 + src/keymap/keymaps/toshiba-satellite_a110 | 10 + src/keymap/keymaps/toshiba-satellite_m30x | 6 + src/keymap/keymaps/zepto-znote | 11 + src/libudev-queue.c | 2 +- src/mtd_probe/.gitignore | 1 + src/mtd_probe/75-probe_mtd.rules | 8 + src/mtd_probe/mtd_probe.c | 51 + src/mtd_probe/mtd_probe.h | 49 + src/mtd_probe/probe_smartmedia.c | 97 ++ src/qemu/42-qemu-usb.rules | 13 + src/rule_generator/75-cd-aliases-generator.rules | 9 + .../75-persistent-net-generator.rules | 102 ++ src/rule_generator/rule_generator.functions | 113 ++ src/rule_generator/write_cd_rules | 126 +++ src/rule_generator/write_net_rules | 141 +++ src/scsi_id/.gitignore | 3 + src/scsi_id/README | 4 + src/scsi_id/scsi.h | 97 ++ src/scsi_id/scsi_id.8 | 119 +++ src/scsi_id/scsi_id.c | 657 ++++++++++++ src/scsi_id/scsi_id.h | 73 ++ src/scsi_id/scsi_serial.c | 990 ++++++++++++++++++ src/v4l_id/.gitignore | 1 + src/v4l_id/60-persistent-v4l.rules | 20 + src/v4l_id/v4l_id.c | 87 ++ 266 files changed, 11026 insertions(+), 11026 deletions(-) create mode 100644 src/accelerometer/.gitignore create mode 100644 src/accelerometer/61-accelerometer.rules create mode 100644 src/accelerometer/accelerometer.c create mode 100644 src/ata_id/.gitignore create mode 100644 src/ata_id/ata_id.c create mode 100644 src/cdrom_id/.gitignore create mode 100644 src/cdrom_id/60-cdrom_id.rules create mode 100644 src/cdrom_id/cdrom_id.c create mode 100644 src/collect/.gitignore create mode 100644 src/collect/collect.c create mode 100644 src/edd_id/.gitignore create mode 100644 src/edd_id/61-persistent-storage-edd.rules create mode 100644 src/edd_id/edd_id.c delete mode 100644 src/extras/accelerometer/.gitignore delete mode 100644 src/extras/accelerometer/61-accelerometer.rules delete mode 100644 src/extras/accelerometer/accelerometer.c delete mode 100644 src/extras/ata_id/.gitignore delete mode 100644 src/extras/ata_id/ata_id.c delete mode 100644 src/extras/cdrom_id/.gitignore delete mode 100644 src/extras/cdrom_id/60-cdrom_id.rules delete mode 100644 src/extras/cdrom_id/cdrom_id.c delete mode 100644 src/extras/collect/.gitignore delete mode 100644 src/extras/collect/collect.c delete mode 100644 src/extras/edd_id/.gitignore delete mode 100644 src/extras/edd_id/61-persistent-storage-edd.rules delete mode 100644 src/extras/edd_id/edd_id.c delete mode 100644 src/extras/floppy/.gitignore delete mode 100644 src/extras/floppy/60-floppy.rules delete mode 100644 src/extras/floppy/create_floppy_devices.c delete mode 100644 src/extras/gudev/.gitignore delete mode 100644 src/extras/gudev/COPYING delete mode 100644 src/extras/gudev/docs/.gitignore delete mode 100644 src/extras/gudev/docs/Makefile.am delete mode 100644 src/extras/gudev/docs/gudev-docs.xml delete mode 100644 src/extras/gudev/docs/gudev-sections.txt delete mode 100644 src/extras/gudev/docs/gudev.types delete mode 100644 src/extras/gudev/docs/version.xml.in delete mode 100755 src/extras/gudev/gjs-example.js delete mode 100644 src/extras/gudev/gudev-1.0.pc.in delete mode 100644 src/extras/gudev/gudev.h delete mode 100644 src/extras/gudev/gudevclient.c delete mode 100644 src/extras/gudev/gudevclient.h delete mode 100644 src/extras/gudev/gudevdevice.c delete mode 100644 src/extras/gudev/gudevdevice.h delete mode 100644 src/extras/gudev/gudevenumerator.c delete mode 100644 src/extras/gudev/gudevenumerator.h delete mode 100644 src/extras/gudev/gudevenums.h delete mode 100644 src/extras/gudev/gudevenumtypes.c.template delete mode 100644 src/extras/gudev/gudevenumtypes.h.template delete mode 100644 src/extras/gudev/gudevmarshal.list delete mode 100644 src/extras/gudev/gudevprivate.h delete mode 100644 src/extras/gudev/gudevtypes.h delete mode 100755 src/extras/gudev/seed-example-enum.js delete mode 100755 src/extras/gudev/seed-example.js delete mode 100644 src/extras/keymap/.gitignore delete mode 100644 src/extras/keymap/95-keyboard-force-release.rules delete mode 100644 src/extras/keymap/95-keymap.rules delete mode 100644 src/extras/keymap/README.keymap.txt delete mode 100755 src/extras/keymap/check-keymaps.sh delete mode 100755 src/extras/keymap/findkeyboards delete mode 100644 src/extras/keymap/force-release-maps/common-volume-keys delete mode 100644 src/extras/keymap/force-release-maps/dell-touchpad delete mode 100644 src/extras/keymap/force-release-maps/hp-other delete mode 100644 src/extras/keymap/force-release-maps/samsung-other delete mode 100755 src/extras/keymap/keyboard-force-release.sh.in delete mode 100644 src/extras/keymap/keymap.c delete mode 100644 src/extras/keymap/keymaps/acer delete mode 100644 src/extras/keymap/keymaps/acer-aspire_5720 delete mode 100644 src/extras/keymap/keymaps/acer-aspire_5920g delete mode 100644 src/extras/keymap/keymaps/acer-aspire_6920 delete mode 100644 src/extras/keymap/keymaps/acer-aspire_8930 delete mode 100644 src/extras/keymap/keymaps/acer-travelmate_c300 delete mode 100644 src/extras/keymap/keymaps/asus delete mode 100644 src/extras/keymap/keymaps/compaq-e_evo delete mode 100644 src/extras/keymap/keymaps/dell delete mode 100644 src/extras/keymap/keymaps/dell-latitude-xt2 delete mode 100644 src/extras/keymap/keymaps/everex-xt5000 delete mode 100644 src/extras/keymap/keymaps/fujitsu-amilo_li_2732 delete mode 100644 src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 delete mode 100644 src/extras/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 delete mode 100644 src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 delete mode 100644 src/extras/keymap/keymaps/fujitsu-amilo_si_1520 delete mode 100644 src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v5 delete mode 100644 src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v6 delete mode 100644 src/extras/keymap/keymaps/genius-slimstar-320 delete mode 100644 src/extras/keymap/keymaps/hewlett-packard delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-2510p_2530p delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-compaq_elitebook delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-pavilion delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-presario-2100 delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-tablet delete mode 100644 src/extras/keymap/keymaps/hewlett-packard-tx2 delete mode 100644 src/extras/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint delete mode 100644 src/extras/keymap/keymaps/inventec-symphony_6.0_7.0 delete mode 100644 src/extras/keymap/keymaps/lenovo-3000 delete mode 100644 src/extras/keymap/keymaps/lenovo-ideapad delete mode 100644 src/extras/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint delete mode 100644 src/extras/keymap/keymaps/lenovo-thinkpad_x200_tablet delete mode 100644 src/extras/keymap/keymaps/lenovo-thinkpad_x6_tablet delete mode 100644 src/extras/keymap/keymaps/lg-x110 delete mode 100644 src/extras/keymap/keymaps/logitech-wave delete mode 100644 src/extras/keymap/keymaps/logitech-wave-cordless delete mode 100644 src/extras/keymap/keymaps/logitech-wave-pro-cordless delete mode 100644 src/extras/keymap/keymaps/maxdata-pro_7000 delete mode 100644 src/extras/keymap/keymaps/medion-fid2060 delete mode 100644 src/extras/keymap/keymaps/medionnb-a555 delete mode 100644 src/extras/keymap/keymaps/micro-star delete mode 100644 src/extras/keymap/keymaps/module-asus-w3j delete mode 100644 src/extras/keymap/keymaps/module-ibm delete mode 100644 src/extras/keymap/keymaps/module-lenovo delete mode 100644 src/extras/keymap/keymaps/module-sony delete mode 100644 src/extras/keymap/keymaps/module-sony-old delete mode 100644 src/extras/keymap/keymaps/module-sony-vgn delete mode 100644 src/extras/keymap/keymaps/olpc-xo delete mode 100644 src/extras/keymap/keymaps/onkyo delete mode 100644 src/extras/keymap/keymaps/oqo-model2 delete mode 100644 src/extras/keymap/keymaps/samsung-other delete mode 100644 src/extras/keymap/keymaps/samsung-sq1us delete mode 100644 src/extras/keymap/keymaps/samsung-sx20s delete mode 100644 src/extras/keymap/keymaps/toshiba-satellite_a100 delete mode 100644 src/extras/keymap/keymaps/toshiba-satellite_a110 delete mode 100644 src/extras/keymap/keymaps/toshiba-satellite_m30x delete mode 100644 src/extras/keymap/keymaps/zepto-znote delete mode 100644 src/extras/mtd_probe/.gitignore delete mode 100644 src/extras/mtd_probe/75-probe_mtd.rules delete mode 100644 src/extras/mtd_probe/mtd_probe.c delete mode 100644 src/extras/mtd_probe/mtd_probe.h delete mode 100644 src/extras/mtd_probe/probe_smartmedia.c delete mode 100644 src/extras/qemu/42-qemu-usb.rules delete mode 100644 src/extras/rule_generator/75-cd-aliases-generator.rules delete mode 100644 src/extras/rule_generator/75-persistent-net-generator.rules delete mode 100644 src/extras/rule_generator/rule_generator.functions delete mode 100644 src/extras/rule_generator/write_cd_rules delete mode 100644 src/extras/rule_generator/write_net_rules delete mode 100644 src/extras/scsi_id/.gitignore delete mode 100644 src/extras/scsi_id/README delete mode 100644 src/extras/scsi_id/scsi.h delete mode 100644 src/extras/scsi_id/scsi_id.8 delete mode 100644 src/extras/scsi_id/scsi_id.c delete mode 100644 src/extras/scsi_id/scsi_id.h delete mode 100644 src/extras/scsi_id/scsi_serial.c delete mode 100644 src/extras/v4l_id/.gitignore delete mode 100644 src/extras/v4l_id/60-persistent-v4l.rules delete mode 100644 src/extras/v4l_id/v4l_id.c create mode 100644 src/floppy/.gitignore create mode 100644 src/floppy/60-floppy.rules create mode 100644 src/floppy/create_floppy_devices.c create mode 100644 src/gudev/.gitignore create mode 100644 src/gudev/COPYING create mode 100644 src/gudev/docs/.gitignore create mode 100644 src/gudev/docs/Makefile.am create mode 100644 src/gudev/docs/gudev-docs.xml create mode 100644 src/gudev/docs/gudev-sections.txt create mode 100644 src/gudev/docs/gudev.types create mode 100644 src/gudev/docs/version.xml.in create mode 100755 src/gudev/gjs-example.js create mode 100644 src/gudev/gudev-1.0.pc.in create mode 100644 src/gudev/gudev.h create mode 100644 src/gudev/gudevclient.c create mode 100644 src/gudev/gudevclient.h create mode 100644 src/gudev/gudevdevice.c create mode 100644 src/gudev/gudevdevice.h create mode 100644 src/gudev/gudevenumerator.c create mode 100644 src/gudev/gudevenumerator.h create mode 100644 src/gudev/gudevenums.h create mode 100644 src/gudev/gudevenumtypes.c.template create mode 100644 src/gudev/gudevenumtypes.h.template create mode 100644 src/gudev/gudevmarshal.list create mode 100644 src/gudev/gudevprivate.h create mode 100644 src/gudev/gudevtypes.h create mode 100755 src/gudev/seed-example-enum.js create mode 100755 src/gudev/seed-example.js create mode 100644 src/keymap/.gitignore create mode 100644 src/keymap/95-keyboard-force-release.rules create mode 100644 src/keymap/95-keymap.rules create mode 100644 src/keymap/README.keymap.txt create mode 100755 src/keymap/check-keymaps.sh create mode 100755 src/keymap/findkeyboards create mode 100644 src/keymap/force-release-maps/common-volume-keys create mode 100644 src/keymap/force-release-maps/dell-touchpad create mode 100644 src/keymap/force-release-maps/hp-other create mode 100644 src/keymap/force-release-maps/samsung-other create mode 100755 src/keymap/keyboard-force-release.sh.in create mode 100644 src/keymap/keymap.c create mode 100644 src/keymap/keymaps/acer create mode 100644 src/keymap/keymaps/acer-aspire_5720 create mode 100644 src/keymap/keymaps/acer-aspire_5920g create mode 100644 src/keymap/keymaps/acer-aspire_6920 create mode 100644 src/keymap/keymaps/acer-aspire_8930 create mode 100644 src/keymap/keymaps/acer-travelmate_c300 create mode 100644 src/keymap/keymaps/asus create mode 100644 src/keymap/keymaps/compaq-e_evo create mode 100644 src/keymap/keymaps/dell create mode 100644 src/keymap/keymaps/dell-latitude-xt2 create mode 100644 src/keymap/keymaps/everex-xt5000 create mode 100644 src/keymap/keymaps/fujitsu-amilo_li_2732 create mode 100644 src/keymap/keymaps/fujitsu-amilo_pa_2548 create mode 100644 src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 create mode 100644 src/keymap/keymaps/fujitsu-amilo_pro_v3205 create mode 100644 src/keymap/keymaps/fujitsu-amilo_si_1520 create mode 100644 src/keymap/keymaps/fujitsu-esprimo_mobile_v5 create mode 100644 src/keymap/keymaps/fujitsu-esprimo_mobile_v6 create mode 100644 src/keymap/keymaps/genius-slimstar-320 create mode 100644 src/keymap/keymaps/hewlett-packard create mode 100644 src/keymap/keymaps/hewlett-packard-2510p_2530p create mode 100644 src/keymap/keymaps/hewlett-packard-compaq_elitebook create mode 100644 src/keymap/keymaps/hewlett-packard-pavilion create mode 100644 src/keymap/keymaps/hewlett-packard-presario-2100 create mode 100644 src/keymap/keymaps/hewlett-packard-tablet create mode 100644 src/keymap/keymaps/hewlett-packard-tx2 create mode 100644 src/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint create mode 100644 src/keymap/keymaps/inventec-symphony_6.0_7.0 create mode 100644 src/keymap/keymaps/lenovo-3000 create mode 100644 src/keymap/keymaps/lenovo-ideapad create mode 100644 src/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint create mode 100644 src/keymap/keymaps/lenovo-thinkpad_x200_tablet create mode 100644 src/keymap/keymaps/lenovo-thinkpad_x6_tablet create mode 100644 src/keymap/keymaps/lg-x110 create mode 100644 src/keymap/keymaps/logitech-wave create mode 100644 src/keymap/keymaps/logitech-wave-cordless create mode 100644 src/keymap/keymaps/logitech-wave-pro-cordless create mode 100644 src/keymap/keymaps/maxdata-pro_7000 create mode 100644 src/keymap/keymaps/medion-fid2060 create mode 100644 src/keymap/keymaps/medionnb-a555 create mode 100644 src/keymap/keymaps/micro-star create mode 100644 src/keymap/keymaps/module-asus-w3j create mode 100644 src/keymap/keymaps/module-ibm create mode 100644 src/keymap/keymaps/module-lenovo create mode 100644 src/keymap/keymaps/module-sony create mode 100644 src/keymap/keymaps/module-sony-old create mode 100644 src/keymap/keymaps/module-sony-vgn create mode 100644 src/keymap/keymaps/olpc-xo create mode 100644 src/keymap/keymaps/onkyo create mode 100644 src/keymap/keymaps/oqo-model2 create mode 100644 src/keymap/keymaps/samsung-other create mode 100644 src/keymap/keymaps/samsung-sq1us create mode 100644 src/keymap/keymaps/samsung-sx20s create mode 100644 src/keymap/keymaps/toshiba-satellite_a100 create mode 100644 src/keymap/keymaps/toshiba-satellite_a110 create mode 100644 src/keymap/keymaps/toshiba-satellite_m30x create mode 100644 src/keymap/keymaps/zepto-znote create mode 100644 src/mtd_probe/.gitignore create mode 100644 src/mtd_probe/75-probe_mtd.rules create mode 100644 src/mtd_probe/mtd_probe.c create mode 100644 src/mtd_probe/mtd_probe.h create mode 100644 src/mtd_probe/probe_smartmedia.c create mode 100644 src/qemu/42-qemu-usb.rules create mode 100644 src/rule_generator/75-cd-aliases-generator.rules create mode 100644 src/rule_generator/75-persistent-net-generator.rules create mode 100644 src/rule_generator/rule_generator.functions create mode 100644 src/rule_generator/write_cd_rules create mode 100644 src/rule_generator/write_net_rules create mode 100644 src/scsi_id/.gitignore create mode 100644 src/scsi_id/README create mode 100644 src/scsi_id/scsi.h create mode 100644 src/scsi_id/scsi_id.8 create mode 100644 src/scsi_id/scsi_id.c create mode 100644 src/scsi_id/scsi_id.h create mode 100644 src/scsi_id/scsi_serial.c create mode 100644 src/v4l_id/.gitignore create mode 100644 src/v4l_id/60-persistent-v4l.rules create mode 100644 src/v4l_id/v4l_id.c diff --git a/Makefile.am b/Makefile.am index 95cb52cdda..11b4c8477d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -328,58 +328,58 @@ EXTRA_DIST += test/sys.tar.xz # ------------------------------------------------------------------------------ # ata_id - ATA identify # ------------------------------------------------------------------------------ -src_extras_ata_id_ata_id_SOURCES = src/extras/ata_id/ata_id.c -src_extras_ata_id_ata_id_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/extras/ata_id/ata_id +src_ata_id_ata_id_SOURCES = src/ata_id/ata_id.c +src_ata_id_ata_id_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/ata_id/ata_id # ------------------------------------------------------------------------------ # cdrom_id - optical drive/media capability # ------------------------------------------------------------------------------ -src_extras_cdrom_id_cdrom_id_SOURCES = src/extras/cdrom_id/cdrom_id.c -src_extras_cdrom_id_cdrom_id_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/extras/cdrom_id/cdrom_id -dist_udevrules_DATA += src/extras/cdrom_id/60-cdrom_id.rules +src_cdrom_id_cdrom_id_SOURCES = src/cdrom_id/cdrom_id.c +src_cdrom_id_cdrom_id_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/cdrom_id/cdrom_id +dist_udevrules_DATA += src/cdrom_id/60-cdrom_id.rules # ------------------------------------------------------------------------------ # collect - trigger action when a collection of devices appeared # ------------------------------------------------------------------------------ -src_extras_collect_collect_SOURCES = src/extras/collect/collect.c -src_extras_collect_collect_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/extras/collect/collect +src_collect_collect_SOURCES = src/collect/collect.c +src_collect_collect_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/collect/collect # ------------------------------------------------------------------------------ # scsi_id - SCSI inquiry to get various serial numbers # ------------------------------------------------------------------------------ -src_extras_scsi_id_scsi_id_SOURCES =\ - src/extras/scsi_id/scsi_id.c \ - src/extras/scsi_id/scsi_serial.c \ - src/extras/scsi_id/scsi.h \ - src/extras/scsi_id/scsi_id.h -src_extras_scsi_id_scsi_id_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/extras/scsi_id/scsi_id -dist_man_MANS += src/extras/scsi_id/scsi_id.8 -EXTRA_DIST += src/extras/scsi_id/README +src_scsi_id_scsi_id_SOURCES =\ + src/scsi_id/scsi_id.c \ + src/scsi_id/scsi_serial.c \ + src/scsi_id/scsi.h \ + src/scsi_id/scsi_id.h +src_scsi_id_scsi_id_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/scsi_id/scsi_id +dist_man_MANS += src/scsi_id/scsi_id.8 +EXTRA_DIST += src/scsi_id/README # ------------------------------------------------------------------------------ # v4l_id - video4linux capabilities # ------------------------------------------------------------------------------ -src_extras_v4l_id_v4l_id_SOURCES = src/extras/v4l_id/v4l_id.c -src_extras_v4l_id_v4l_id_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/extras/v4l_id/v4l_id -dist_udevrules_DATA += src/extras/v4l_id/60-persistent-v4l.rules +src_v4l_id_v4l_id_SOURCES = src/v4l_id/v4l_id.c +src_v4l_id_v4l_id_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/v4l_id/v4l_id +dist_udevrules_DATA += src/v4l_id/60-persistent-v4l.rules # ------------------------------------------------------------------------------ # accelerometer - updates device orientation # ------------------------------------------------------------------------------ -src_extras_accelerometer_accelerometer_SOURCES = src/extras/accelerometer/accelerometer.c -src_extras_accelerometer_accelerometer_LDADD = src/libudev-private.la -lm -pkglibexec_PROGRAMS += src/extras/accelerometer/accelerometer -dist_udevrules_DATA += src/extras/accelerometer/61-accelerometer.rules +src_accelerometer_accelerometer_SOURCES = src/accelerometer/accelerometer.c +src_accelerometer_accelerometer_LDADD = src/libudev-private.la -lm +pkglibexec_PROGRAMS += src/accelerometer/accelerometer +dist_udevrules_DATA += src/accelerometer/61-accelerometer.rules # ------------------------------------------------------------------------------ # qemu -- qemu/kvm guest tweaks # ------------------------------------------------------------------------------ -dist_udevrules_DATA += src/extras/qemu/42-qemu-usb.rules +dist_udevrules_DATA += src/qemu/42-qemu-usb.rules if ENABLE_GUDEV # ------------------------------------------------------------------------------ @@ -389,91 +389,91 @@ LIBGUDEV_CURRENT=1 LIBGUDEV_REVISION=1 LIBGUDEV_AGE=1 -SUBDIRS += src/extras/gudev/docs - -src_extras_gudev_libgudev_includedir=$(includedir)/gudev-1.0/gudev -src_extras_gudev_libgudev_include_HEADERS = \ - src/extras/gudev/gudev.h \ - src/extras/gudev/gudevenums.h \ - src/extras/gudev/gudevenumtypes.h \ - src/extras/gudev/gudevtypes.h \ - src/extras/gudev/gudevclient.h \ - src/extras/gudev/gudevdevice.h \ - src/extras/gudev/gudevenumerator.h - -lib_LTLIBRARIES += src/extras/gudev/libgudev-1.0.la - -pkgconfig_DATA += src/extras/gudev/gudev-1.0.pc -EXTRA_DIST += src/extras/gudev/gudev-1.0.pc.in -CLEANFILES += src/extras/gudev/gudev-1.0.pc - -src_extras_gudev_libgudev_1_0_la_SOURCES = \ - src/extras/gudev/gudevenums.h \ - src/extras/gudev/gudevenumtypes.h \ - src/extras/gudev/gudevenumtypes.h\ - src/extras/gudev/gudevtypes.h \ - src/extras/gudev/gudevclient.h \ - src/extras/gudev/gudevclient.c \ - src/extras/gudev/gudevdevice.h \ - src/extras/gudev/gudevdevice.c \ - src/extras/gudev/gudevenumerator.h \ - src/extras/gudev/gudevenumerator.c \ - src/extras/gudev/gudevprivate.h - -nodist_src_extras_gudev_libgudev_1_0_la_SOURCES = \ - src/extras/gudev/gudevmarshal.h \ - src/extras/gudev/gudevmarshal.c \ - src/extras/gudev/gudevenumtypes.h \ - src/extras/gudev/gudevenumtypes.c -BUILT_SOURCES += $(nodist_src_extras_gudev_libgudev_1_0_la_SOURCES) - -src_extras_gudev_libgudev_1_0_la_CPPFLAGS = \ +SUBDIRS += src/gudev/docs + +src_gudev_libgudev_includedir=$(includedir)/gudev-1.0/gudev +src_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 += src/gudev/libgudev-1.0.la + +pkgconfig_DATA += src/gudev/gudev-1.0.pc +EXTRA_DIST += src/gudev/gudev-1.0.pc.in +CLEANFILES += src/gudev/gudev-1.0.pc + +src_gudev_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_src_gudev_libgudev_1_0_la_SOURCES = \ + src/gudev/gudevmarshal.h \ + src/gudev/gudevmarshal.c \ + src/gudev/gudevenumtypes.h \ + src/gudev/gudevenumtypes.c +BUILT_SOURCES += $(nodist_src_gudev_libgudev_1_0_la_SOURCES) + +src_gudev_libgudev_1_0_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ - -I$(top_builddir)/src/extras \ - -I$(top_srcdir)/src/extras \ - -I$(top_builddir)/src/extras/gudev \ - -I$(top_srcdir)/src/extras/gudev \ + -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\" -src_extras_gudev_libgudev_1_0_la_CFLAGS = \ +src_gudev_libgudev_1_0_la_CFLAGS = \ -fvisibility=default \ $(GLIB_CFLAGS) -src_extras_gudev_libgudev_1_0_la_LIBADD = src/libudev.la $(GLIB_LIBS) +src_gudev_libgudev_1_0_la_LIBADD = src/libudev.la $(GLIB_LIBS) -src_extras_gudev_libgudev_1_0_la_LDFLAGS = \ +src_gudev_libgudev_1_0_la_LDFLAGS = \ -version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \ -export-dynamic -no-undefined \ -export-symbols-regex '^g_udev_.*' EXTRA_DIST += \ - src/extras/gudev/COPYING \ - src/extras/gudev/gudevmarshal.list \ - src/extras/gudev/gudevenumtypes.h.template \ - src/extras/gudev/gudevenumtypes.c.template \ - src/extras/gudev/gjs-example.js \ - src/extras/gudev/seed-example-enum.js \ - src/extras/gudev/seed-example.js - -src/extras/gudev/gudevmarshal.h: src/extras/gudev/gudevmarshal.list + src/gudev/COPYING \ + 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 + +src/gudev/gudevmarshal.h: src/gudev/gudevmarshal.list $(AM_V_GEN)glib-genmarshal $< --prefix=g_udev_marshal --header > $@ -src/extras/gudev/gudevmarshal.c: src/extras/gudev/gudevmarshal.list +src/gudev/gudevmarshal.c: src/gudev/gudevmarshal.list $(AM_V_GEN)echo "#include \"gudevmarshal.h\"" > $@ && \ glib-genmarshal $< --prefix=g_udev_marshal --body >> $@ -src/extras/gudev/gudevenumtypes.h: src/extras/gudev/gudevenumtypes.h.template src/extras/gudev/gudevenums.h +src/gudev/gudevenumtypes.h: src/gudev/gudevenumtypes.h.template src/gudev/gudevenums.h $(AM_V_GEN)glib-mkenums --template $^ > \ $@.tmp && mv $@.tmp $@ -src/extras/gudev/gudevenumtypes.c: src/extras/gudev/gudevenumtypes.c.template src/extras/gudev/gudevenums.h +src/gudev/gudevenumtypes.c: src/gudev/gudevenumtypes.c.template src/gudev/gudevenums.h $(AM_V_GEN)glib-mkenums --template $^ > \ $@.tmp && mv $@.tmp $@ if ENABLE_INTROSPECTION -src/extras/gudev/GUdev-1.0.gir: src/extras/gudev/libgudev-1.0.la $(G_IR_SCANNER) +src/gudev/GUdev-1.0.gir: src/gudev/libgudev-1.0.la $(G_IR_SCANNER) $(AM_V_GEN)$(G_IR_SCANNER) -v \ --warn-all \ --namespace GUdev \ @@ -481,35 +481,35 @@ src/extras/gudev/GUdev-1.0.gir: src/extras/gudev/libgudev-1.0.la $(G_IR_SCANNER) --include=GObject-2.0 \ --library=gudev-1.0 \ --library-path=$(top_builddir)/src \ - --library-path=$(top_builddir)/src/extras/gudev \ + --library-path=$(top_builddir)/src/gudev \ --output $@ \ --pkg=glib-2.0 \ --pkg=gobject-2.0 \ --pkg-export=gudev-1.0 \ --c-include=gudev/gudev.h \ - -I$(top_srcdir)/src/extras \ - -I$(top_builddir)/src/extras \ + -I$(top_srcdir)/src/\ + -I$(top_builddir)/src/\ -D_GUDEV_COMPILATION \ -D_GUDEV_WORK_AROUND_DEV_T_BUG \ - $(top_srcdir)/src/extras/gudev/gudev.h \ - $(top_srcdir)/src/extras/gudev/gudevtypes.h \ - $(top_srcdir)/src/extras/gudev/gudevenums.h \ - $(or $(wildcard $(top_builddir)/src/extras/gudev/gudevenumtypes.h),$(top_srcdir)/src/extras/gudev/gudevenumtypes.h) \ - $(top_srcdir)/src/extras/gudev/gudevclient.h \ - $(top_srcdir)/src/extras/gudev/gudevdevice.h \ - $(top_srcdir)/src/extras/gudev/gudevenumerator.h \ - $(top_srcdir)/src/extras/gudev/gudevclient.c \ - $(top_srcdir)/src/extras/gudev/gudevdevice.c \ - $(top_srcdir)/src/extras/gudev/gudevenumerator.c - -src/extras/gudev/GUdev-1.0.typelib: src/extras/gudev/GUdev-1.0.gir $(G_IR_COMPILER) + $(top_srcdir)/src/gudev/gudev.h \ + $(top_srcdir)/src/gudev/gudevtypes.h \ + $(top_srcdir)/src/gudev/gudevenums.h \ + $(or $(wildcard $(top_builddir)/src/gudev/gudevenumtypes.h),$(top_srcdir)/src/gudev/gudevenumtypes.h) \ + $(top_srcdir)/src/gudev/gudevclient.h \ + $(top_srcdir)/src/gudev/gudevdevice.h \ + $(top_srcdir)/src/gudev/gudevenumerator.h \ + $(top_srcdir)/src/gudev/gudevclient.c \ + $(top_srcdir)/src/gudev/gudevdevice.c \ + $(top_srcdir)/src/gudev/gudevenumerator.c + +src/gudev/GUdev-1.0.typelib: src/gudev/GUdev-1.0.gir $(G_IR_COMPILER) $(AM_V_GEN)g-ir-compiler $< -o $@ girdir = $(GIRDIR) -gir_DATA = src/extras/gudev/GUdev-1.0.gir +gir_DATA = src/gudev/GUdev-1.0.gir typelibsdir = $(GIRTYPELIBDIR) -typelibs_DATA = src/extras/gudev/GUdev-1.0.typelib +typelibs_DATA = src/gudev/GUdev-1.0.typelib CLEANFILES += $(gir_DATA) $(typelibs_DATA) endif # ENABLE_INTROSPECTION @@ -535,114 +535,114 @@ if ENABLE_KEYMAP # ------------------------------------------------------------------------------ # keymap - map custom hardware's multimedia keys # ------------------------------------------------------------------------------ -src_extras_keymap_keymap_SOURCES = src/extras/keymap/keymap.c -src_extras_keymap_keymap_CPPFLAGS = $(AM_CPPFLAGS) -I src/extras/keymap -nodist_src_extras_keymap_keymap_SOURCES = \ - src/extras/keymap/keys-from-name.h \ - src/extras/keymap/keys-to-name.h -BUILT_SOURCES += $(nodist_src_extras_keymap_keymap_SOURCES) +src_keymap_keymap_SOURCES = src/keymap/keymap.c +src_keymap_keymap_CPPFLAGS = $(AM_CPPFLAGS) -I src/keymap +nodist_src_keymap_keymap_SOURCES = \ + src/keymap/keys-from-name.h \ + src/keymap/keys-to-name.h +BUILT_SOURCES += $(nodist_src_keymap_keymap_SOURCES) -pkglibexec_PROGRAMS += src/extras/keymap/keymap -dist_doc_DATA = src/extras/keymap/README.keymap.txt +pkglibexec_PROGRAMS += src/keymap/keymap +dist_doc_DATA = src/keymap/README.keymap.txt dist_udevrules_DATA += \ - src/extras/keymap/95-keymap.rules \ - src/extras/keymap/95-keyboard-force-release.rules + src/keymap/95-keymap.rules \ + src/keymap/95-keyboard-force-release.rules -dist_udevhome_SCRIPTS += src/extras/keymap/findkeyboards -udevhome_SCRIPTS += src/extras/keymap/keyboard-force-release.sh +dist_udevhome_SCRIPTS += src/keymap/findkeyboards +udevhome_SCRIPTS += src/keymap/keyboard-force-release.sh EXTRA_DIST += \ - src/extras/keymap/check-keymaps.sh \ - src/extras/keymap/keyboard-force-release.sh.in + src/keymap/check-keymaps.sh \ + src/keymap/keyboard-force-release.sh.in CLEANFILES += \ - src/extras/keymap/keys.txt \ - src/extras/keymap/keys-from-name.gperf \ - src/extras/keymap/keyboard-force-release.sh + src/keymap/keys.txt \ + src/keymap/keys-from-name.gperf \ + src/keymap/keyboard-force-release.sh udevkeymapdir = $(libexecdir)/udev/keymaps dist_udevkeymap_DATA = \ - src/extras/keymap/keymaps/acer \ - src/extras/keymap/keymaps/acer-aspire_5720 \ - src/extras/keymap/keymaps/acer-aspire_8930 \ - src/extras/keymap/keymaps/acer-aspire_5920g \ - src/extras/keymap/keymaps/acer-aspire_6920 \ - src/extras/keymap/keymaps/acer-travelmate_c300 \ - src/extras/keymap/keymaps/asus \ - src/extras/keymap/keymaps/compaq-e_evo \ - src/extras/keymap/keymaps/dell \ - src/extras/keymap/keymaps/dell-latitude-xt2 \ - src/extras/keymap/keymaps/everex-xt5000 \ - src/extras/keymap/keymaps/fujitsu-amilo_li_2732 \ - src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 \ - src/extras/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 \ - src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 \ - src/extras/keymap/keymaps/fujitsu-amilo_si_1520 \ - src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v5 \ - src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v6 \ - src/extras/keymap/keymaps/genius-slimstar-320 \ - src/extras/keymap/keymaps/hewlett-packard \ - src/extras/keymap/keymaps/hewlett-packard-2510p_2530p \ - src/extras/keymap/keymaps/hewlett-packard-compaq_elitebook \ - src/extras/keymap/keymaps/hewlett-packard-pavilion \ - src/extras/keymap/keymaps/hewlett-packard-presario-2100 \ - src/extras/keymap/keymaps/hewlett-packard-tablet \ - src/extras/keymap/keymaps/hewlett-packard-tx2 \ - src/extras/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint \ - src/extras/keymap/keymaps/inventec-symphony_6.0_7.0 \ - src/extras/keymap/keymaps/lenovo-3000 \ - src/extras/keymap/keymaps/lenovo-ideapad \ - src/extras/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \ - src/extras/keymap/keymaps/lenovo-thinkpad_x6_tablet \ - src/extras/keymap/keymaps/lenovo-thinkpad_x200_tablet \ - src/extras/keymap/keymaps/lg-x110 \ - src/extras/keymap/keymaps/logitech-wave \ - src/extras/keymap/keymaps/logitech-wave-cordless \ - src/extras/keymap/keymaps/logitech-wave-pro-cordless \ - src/extras/keymap/keymaps/maxdata-pro_7000 \ - src/extras/keymap/keymaps/medion-fid2060 \ - src/extras/keymap/keymaps/medionnb-a555 \ - src/extras/keymap/keymaps/micro-star \ - src/extras/keymap/keymaps/module-asus-w3j \ - src/extras/keymap/keymaps/module-ibm \ - src/extras/keymap/keymaps/module-lenovo \ - src/extras/keymap/keymaps/module-sony \ - src/extras/keymap/keymaps/module-sony-old \ - src/extras/keymap/keymaps/module-sony-vgn \ - src/extras/keymap/keymaps/olpc-xo \ - src/extras/keymap/keymaps/onkyo \ - src/extras/keymap/keymaps/oqo-model2 \ - src/extras/keymap/keymaps/samsung-other \ - src/extras/keymap/keymaps/samsung-sq1us \ - src/extras/keymap/keymaps/samsung-sx20s \ - src/extras/keymap/keymaps/toshiba-satellite_a100 \ - src/extras/keymap/keymaps/toshiba-satellite_a110 \ - src/extras/keymap/keymaps/toshiba-satellite_m30x \ - src/extras/keymap/keymaps/zepto-znote + src/keymap/keymaps/acer \ + src/keymap/keymaps/acer-aspire_5720 \ + src/keymap/keymaps/acer-aspire_8930 \ + src/keymap/keymaps/acer-aspire_5920g \ + src/keymap/keymaps/acer-aspire_6920 \ + src/keymap/keymaps/acer-travelmate_c300 \ + src/keymap/keymaps/asus \ + src/keymap/keymaps/compaq-e_evo \ + src/keymap/keymaps/dell \ + src/keymap/keymaps/dell-latitude-xt2 \ + src/keymap/keymaps/everex-xt5000 \ + src/keymap/keymaps/fujitsu-amilo_li_2732 \ + src/keymap/keymaps/fujitsu-amilo_pa_2548 \ + src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 \ + src/keymap/keymaps/fujitsu-amilo_pro_v3205 \ + src/keymap/keymaps/fujitsu-amilo_si_1520 \ + src/keymap/keymaps/fujitsu-esprimo_mobile_v5 \ + src/keymap/keymaps/fujitsu-esprimo_mobile_v6 \ + src/keymap/keymaps/genius-slimstar-320 \ + src/keymap/keymaps/hewlett-packard \ + src/keymap/keymaps/hewlett-packard-2510p_2530p \ + src/keymap/keymaps/hewlett-packard-compaq_elitebook \ + src/keymap/keymaps/hewlett-packard-pavilion \ + src/keymap/keymaps/hewlett-packard-presario-2100 \ + src/keymap/keymaps/hewlett-packard-tablet \ + src/keymap/keymaps/hewlett-packard-tx2 \ + src/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint \ + src/keymap/keymaps/inventec-symphony_6.0_7.0 \ + src/keymap/keymaps/lenovo-3000 \ + src/keymap/keymaps/lenovo-ideapad \ + src/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \ + src/keymap/keymaps/lenovo-thinkpad_x6_tablet \ + src/keymap/keymaps/lenovo-thinkpad_x200_tablet \ + src/keymap/keymaps/lg-x110 \ + src/keymap/keymaps/logitech-wave \ + src/keymap/keymaps/logitech-wave-cordless \ + src/keymap/keymaps/logitech-wave-pro-cordless \ + src/keymap/keymaps/maxdata-pro_7000 \ + src/keymap/keymaps/medion-fid2060 \ + src/keymap/keymaps/medionnb-a555 \ + src/keymap/keymaps/micro-star \ + src/keymap/keymaps/module-asus-w3j \ + src/keymap/keymaps/module-ibm \ + src/keymap/keymaps/module-lenovo \ + src/keymap/keymaps/module-sony \ + src/keymap/keymaps/module-sony-old \ + src/keymap/keymaps/module-sony-vgn \ + src/keymap/keymaps/olpc-xo \ + src/keymap/keymaps/onkyo \ + src/keymap/keymaps/oqo-model2 \ + src/keymap/keymaps/samsung-other \ + src/keymap/keymaps/samsung-sq1us \ + src/keymap/keymaps/samsung-sx20s \ + src/keymap/keymaps/toshiba-satellite_a100 \ + src/keymap/keymaps/toshiba-satellite_a110 \ + src/keymap/keymaps/toshiba-satellite_m30x \ + src/keymap/keymaps/zepto-znote udevkeymapforcereldir = $(libexecdir)/udev/keymaps/force-release dist_udevkeymapforcerel_DATA = \ - src/extras/keymap/force-release-maps/dell-touchpad \ - src/extras/keymap/force-release-maps/hp-other \ - src/extras/keymap/force-release-maps/samsung-other \ - src/extras/keymap/force-release-maps/common-volume-keys + src/keymap/force-release-maps/dell-touchpad \ + src/keymap/force-release-maps/hp-other \ + src/keymap/force-release-maps/samsung-other \ + src/keymap/force-release-maps/common-volume-keys -src/extras/keymap/keys.txt: $(INCLUDE_PREFIX)/linux/input.h - $(AM_V_at)mkdir -p src/extras/keymap +src/keymap/keys.txt: $(INCLUDE_PREFIX)/linux/input.h + $(AM_V_at)mkdir -p src/keymap $(AM_V_GEN)$(AWK) '/^#define.*KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' < $< | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@ -src/extras/keymap/keys-from-name.gperf: src/extras/keymap/keys.txt +src/keymap/keys-from-name.gperf: src/keymap/keys.txt $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", " $$1 }' < $< > $@ -src/extras/keymap/keys-from-name.h: src/extras/keymap/keys-from-name.gperf Makefile +src/keymap/keys-from-name.h: src/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/extras/keymap/keys-to-name.h: src/extras/keymap/keys.txt Makefile +src/keymap/keys-to-name.h: src/keymap/keys.txt Makefile $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@ -keymaps-distcheck-hook: src/extras/keymap/keys.txt - $(top_srcdir)/src/extras/keymap/check-keymaps.sh $(top_srcdir) $^ +keymaps-distcheck-hook: src/keymap/keys.txt + $(top_srcdir)/src/keymap/check-keymaps.sh $(top_srcdir) $^ DISTCHECK_HOOKS += keymaps-distcheck-hook endif @@ -650,13 +650,13 @@ if ENABLE_MTD_PROBE # ------------------------------------------------------------------------------ # mtd_probe - autoloads FTL module for mtd devices # ------------------------------------------------------------------------------ -src_extras_mtd_probe_mtd_probe_SOURCES = \ - src/extras/mtd_probe/mtd_probe.c \ - src/extras/mtd_probe/mtd_probe.h \ - src/extras/mtd_probe/probe_smartmedia.c -src_extras_mtd_probe_mtd_probe_CPPFLAGS = $(AM_CPPFLAGS) -dist_udevrules_DATA += src/extras/mtd_probe/75-probe_mtd.rules -pkglibexec_PROGRAMS += src/extras/mtd_probe/mtd_probe +src_mtd_probe_mtd_probe_SOURCES = \ + src/mtd_probe/mtd_probe.c \ + src/mtd_probe/mtd_probe.h \ + src/mtd_probe/probe_smartmedia.c +src_mtd_probe_mtd_probe_CPPFLAGS = $(AM_CPPFLAGS) +dist_udevrules_DATA += src/mtd_probe/75-probe_mtd.rules +pkglibexec_PROGRAMS += src/mtd_probe/mtd_probe endif if ENABLE_RULE_GENERATOR @@ -664,35 +664,35 @@ if ENABLE_RULE_GENERATOR # rule_generator - persistent network and optical device rule generator # ------------------------------------------------------------------------------ dist_udevhome_SCRIPTS += \ - src/extras/rule_generator/write_cd_rules \ - src/extras/rule_generator/write_net_rules + src/rule_generator/write_cd_rules \ + src/rule_generator/write_net_rules dist_udevhome_DATA += \ - src/extras/rule_generator/rule_generator.functions + src/rule_generator/rule_generator.functions dist_udevrules_DATA += \ - src/extras/rule_generator/75-cd-aliases-generator.rules \ - src/extras/rule_generator/75-persistent-net-generator.rules + src/rule_generator/75-cd-aliases-generator.rules \ + src/rule_generator/75-persistent-net-generator.rules endif if ENABLE_FLOPPY # ------------------------------------------------------------------------------ # create_floppy_devices - historical floppy kernel device nodes (/dev/fd0h1440, ...) # ------------------------------------------------------------------------------ -src_create_floppy_devices_SOURCES = src/extras/floppy/create_floppy_devices.c +src_create_floppy_devices_SOURCES = src/floppy/create_floppy_devices.c src_create_floppy_devices_LDADD = src/libudev-private.la pkglibexec_PROGRAMS += src/create_floppy_devices -dist_udevrules_DATA += src/extras/floppy/60-floppy.rules +dist_udevrules_DATA += src/floppy/60-floppy.rules endif if ENABLE_EDD # ------------------------------------------------------------------------------ # edd_id - create /dev/disk/by-id/edd-* links for BIOS EDD data # ------------------------------------------------------------------------------ -src_edd_id_SOURCES = src/extras/edd_id/edd_id.c -src_edd_id_LDADD = src/libudev-private.la -pkglibexec_PROGRAMS += src/edd_id -dist_udevrules_DATA += src/extras/edd_id/61-persistent-storage-edd.rules +src__edd_id_edd_id_SOURCES = src/edd_id/edd_id.c +src_edd_id_edd_id_LDADD = src/libudev-private.la +pkglibexec_PROGRAMS += src/edd_id/edd_id +dist_udevrules_DATA += src/edd_id/61-persistent-storage-edd.rules endif # ------------------------------------------------------------------------------ @@ -763,5 +763,5 @@ doc-sync: for i in src/*.html; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/udev/; done for i in src/docs/html/*.{html,css,png}; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done for i in src/docs/html/*.{html,css,png}; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/libudev/; done - for i in src/extras/gudev/docs/html/*.{html,css,png}; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done - for i in src/extras/gudev/docs/html/*.{html,css,png}; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/gudev/; done + for i in src/gudev/docs/html/*.{html,css,png}; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done + for i in src/gudev/docs/html/*.{html,css,png}; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/gudev/; done diff --git a/configure.ac b/configure.ac index 2e750babe8..8f6e004392 100644 --- a/configure.ac +++ b/configure.ac @@ -205,8 +205,8 @@ AC_CONFIG_FILES([ Makefile src/docs/Makefile src/docs/version.xml - src/extras/gudev/docs/Makefile - src/extras/gudev/docs/version.xml + src/gudev/docs/Makefile + src/gudev/docs/version.xml ]) AC_OUTPUT diff --git a/rules/misc/30-kernel-compat.rules b/rules/misc/30-kernel-compat.rules index cddf371d3b..2596095506 100644 --- a/rules/misc/30-kernel-compat.rules +++ b/rules/misc/30-kernel-compat.rules @@ -7,7 +7,7 @@ ACTION!="add", GOTO="kernel_compat_end" -# see src/extras/qemu/42-qemu-usb.rules, version for 2.6.32 + older. +# see src/qemu/42-qemu-usb.rules, version for 2.6.32 + older. ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}=="42", TEST=="power/level", ATTR{power/level}="auto" ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/level", ATTR{power/level}="auto" ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/level", ATTR{power/level}="auto" diff --git a/src/accelerometer/.gitignore b/src/accelerometer/.gitignore new file mode 100644 index 0000000000..dddc2204d4 --- /dev/null +++ b/src/accelerometer/.gitignore @@ -0,0 +1 @@ +accelerometer diff --git a/src/accelerometer/61-accelerometer.rules b/src/accelerometer/61-accelerometer.rules new file mode 100644 index 0000000000..a6a2bfd088 --- /dev/null +++ b/src/accelerometer/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/src/accelerometer/accelerometer.c b/src/accelerometer/accelerometer.c new file mode 100644 index 0000000000..bc9715b264 --- /dev/null +++ b/src/accelerometer/accelerometer.c @@ -0,0 +1,357 @@ +/* + * 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 + * + * orientation_calc() from the sensorfw package + * Copyright (C) 2009-2010 Nokia Corporation + * Authors: + * Üstün Ergenoglu + * Timo Rongas + * Lihan Guo + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(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)) + 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] \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; + + udev_log_init("input_id"); + 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; + if (udev_get_log_priority(udev) < LOG_INFO) + udev_set_log_priority(udev, LOG_INFO); + break; + case 'h': + help(); + exit(0); + default: + exit(1); + } + } + + if (argv[optind] == NULL) { + help(); + exit(1); + } + + /* get the device */ + snprintf(devpath, sizeof(devpath), "%s/%s", udev_get_sys_path(udev), 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_children() instead + * when it's available */ + 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; + } + + info(udev, "Opening accelerometer device %s\n", devnode); + test_orientation(udev, dev, devnode); + free(devnode); + + return 0; +} diff --git a/src/ata_id/.gitignore b/src/ata_id/.gitignore new file mode 100644 index 0000000000..77837266e6 --- /dev/null +++ b/src/ata_id/.gitignore @@ -0,0 +1 @@ +ata_id diff --git a/src/ata_id/ata_id.c b/src/ata_id/ata_id.c new file mode 100644 index 0000000000..257f494496 --- /dev/null +++ b/src/ata_id/ata_id.c @@ -0,0 +1,726 @@ +/* + * ata_id - reads product/serial number from ATA drives + * + * Copyright (C) 2005-2008 Kay Sievers + * Copyright (C) 2009 Lennart Poettering + * Copyright (C) 2009-2010 David Zeuthen + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.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; + + assert(identify != NULL); + assert(dest != NULL); + assert((dest_len & 1) == 0); + + 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; + + assert(out_identify != NULL); + + /* init results */ + ret = -1; + 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; + + udev_log_init("ata_id"); + 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] \n" + " --export print values as environment keys\n" + " --help print this help text\n\n"); + goto exit; + } + } + + node = argv[optind]; + if (node == NULL) { + err(udev, "no node specified\n"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY|O_NONBLOCK); + if (fd < 0) { + err(udev, "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, 6); /* 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) { + if (errno == ENOTTY) { + info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node); + rc = 2; + } else { + err(udev, "HDIO_GET_IDENTITY failed for '%s': %m\n", node); + rc = 3; + } + 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); + udev_log_close(); + return rc; +} diff --git a/src/cdrom_id/.gitignore b/src/cdrom_id/.gitignore new file mode 100644 index 0000000000..7d817ea74e --- /dev/null +++ b/src/cdrom_id/.gitignore @@ -0,0 +1 @@ +cdrom_id diff --git a/src/cdrom_id/60-cdrom_id.rules b/src/cdrom_id/60-cdrom_id.rules new file mode 100644 index 0000000000..6eaf76a72c --- /dev/null +++ b/src/cdrom_id/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/src/cdrom_id/cdrom_id.c b/src/cdrom_id/cdrom_id.c new file mode 100644 index 0000000000..f90d52ec9c --- /dev/null +++ b/src/cdrom_id/cdrom_id.c @@ -0,0 +1,1099 @@ +/* + * cdrom_id - optical drive and media information prober + * + * Copyright (C) 2008-2010 Kay Sievers + * + * 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 . + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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", "r"); + 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, char *cmd, int err) +{ + if (err == -1) { + info(udev, "%s failed\n", cmd); + return; + } + info(udev, "%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) + info(udev, "CDROM_CLEAR_OPTIONS, CDO_LOCK failed\n"); + + err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0); + if (err < 0) + info(udev, "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) { + info(udev, "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) { + info(udev, "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) { + info(udev, "not an MMC unit\n"); + return -1; + } + + info(udev, "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: + info(udev, "profile 0x%02x \n", cur_profile); + cd_media = 1; + cd_media_mo = 1; + break; + case 0x08: + info(udev, "profile 0x%02x media_cd_rom\n", cur_profile); + cd_media = 1; + cd_media_cd_rom = 1; + break; + case 0x09: + info(udev, "profile 0x%02x media_cd_r\n", cur_profile); + cd_media = 1; + cd_media_cd_r = 1; + break; + case 0x0a: + info(udev, "profile 0x%02x media_cd_rw\n", cur_profile); + cd_media = 1; + cd_media_cd_rw = 1; + break; + case 0x10: + info(udev, "profile 0x%02x media_dvd_ro\n", cur_profile); + cd_media = 1; + cd_media_dvd_rom = 1; + break; + case 0x11: + info(udev, "profile 0x%02x media_dvd_r\n", cur_profile); + cd_media = 1; + cd_media_dvd_r = 1; + break; + case 0x12: + info(udev, "profile 0x%02x media_dvd_ram\n", cur_profile); + cd_media = 1; + cd_media_dvd_ram = 1; + break; + case 0x13: + info(udev, "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: + info(udev, "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: + info(udev, "profile 0x%02x media_dvd_plus_r\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_r = 1; + break; + case 0x1A: + info(udev, "profile 0x%02x media_dvd_plus_rw\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_rw = 1; + break; + case 0x2A: + info(udev, "profile 0x%02x media_dvd_plus_rw_dl\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_rw_dl = 1; + break; + case 0x2B: + info(udev, "profile 0x%02x media_dvd_plus_r_dl\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_r_dl = 1; + break; + case 0x40: + info(udev, "profile 0x%02x media_bd\n", cur_profile); + cd_media = 1; + cd_media_bd = 1; + break; + case 0x41: + case 0x42: + info(udev, "profile 0x%02x media_bd_r\n", cur_profile); + cd_media = 1; + cd_media_bd_r = 1; + break; + case 0x43: + info(udev, "profile 0x%02x media_bd_re\n", cur_profile); + cd_media = 1; + cd_media_bd_re = 1; + break; + case 0x50: + info(udev, "profile 0x%02x media_hddvd\n", cur_profile); + cd_media = 1; + cd_media_hddvd = 1; + break; + case 0x51: + info(udev, "profile 0x%02x media_hddvd_r\n", cur_profile); + cd_media = 1; + cd_media_hddvd_r = 1; + break; + case 0x52: + info(udev, "profile 0x%02x media_hddvd_rw\n", cur_profile); + cd_media = 1; + cd_media_hddvd_rw = 1; + break; + default: + info(udev, "profile 0x%02x \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: + info(udev, "profile 0x%02x mo\n", profile); + cd_mo = 1; + break; + case 0x08: + info(udev, "profile 0x%02x cd_rom\n", profile); + cd_cd_rom = 1; + break; + case 0x09: + info(udev, "profile 0x%02x cd_r\n", profile); + cd_cd_r = 1; + break; + case 0x0A: + info(udev, "profile 0x%02x cd_rw\n", profile); + cd_cd_rw = 1; + break; + case 0x10: + info(udev, "profile 0x%02x dvd_rom\n", profile); + cd_dvd_rom = 1; + break; + case 0x12: + info(udev, "profile 0x%02x dvd_ram\n", profile); + cd_dvd_ram = 1; + break; + case 0x13: + case 0x14: + info(udev, "profile 0x%02x dvd_rw\n", profile); + cd_dvd_rw = 1; + break; + case 0x1B: + info(udev, "profile 0x%02x dvd_plus_r\n", profile); + cd_dvd_plus_r = 1; + break; + case 0x1A: + info(udev, "profile 0x%02x dvd_plus_rw\n", profile); + cd_dvd_plus_rw = 1; + break; + case 0x2A: + info(udev, "profile 0x%02x dvd_plus_rw_dl\n", profile); + cd_dvd_plus_rw_dl = 1; + break; + case 0x2B: + info(udev, "profile 0x%02x dvd_plus_r_dl\n", profile); + cd_dvd_plus_r_dl = 1; + break; + case 0x40: + cd_bd = 1; + info(udev, "profile 0x%02x bd\n", profile); + break; + case 0x41: + case 0x42: + cd_bd_r = 1; + info(udev, "profile 0x%02x bd_r\n", profile); + break; + case 0x43: + cd_bd_re = 1; + info(udev, "profile 0x%02x bd_re\n", profile); + break; + case 0x50: + cd_hddvd = 1; + info(udev, "profile 0x%02x hddvd\n", profile); + break; + case 0x51: + cd_hddvd_r = 1; + info(udev, "profile 0x%02x hddvd_r\n", profile); + break; + case 0x52: + cd_hddvd_rw = 1; + info(udev, "profile 0x%02x hddvd_rw\n", profile); + break; + default: + info(udev, "profile 0x%02x \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) { + info(udev, "no current profile, but disc is present; assuming CD-ROM\n"); + cd_media_cd_rom = 1; + return 0; + } else { + info(udev, "no current profile, assuming no media\n"); + return -1; + } + }; + + cd_media = 1; + + if (header[2] & 16) { + cd_media_cd_rw = 1; + info(udev, "profile 0x0a media_cd_rw\n"); + } else if ((header[2] & 3) < 2 && cd_cd_r) { + cd_media_cd_r = 1; + info(udev, "profile 0x09 media_cd_r\n"); + } else { + cd_media_cd_rom = 1; + info(udev, "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) { + info(udev, "drive is pre-MMC2 and does not support 46h get configuration command\n"); + info(udev, "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) { + info(udev, "current profile 0x%02x\n", cur_profile); + feature_profile_media (udev, cur_profile); + ret = 0; /* we have media */ + } else { + info(udev, "no current profile, assuming no media\n"); + } + + len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; + info(udev, "GET CONFIGURATION: size of features buffer 0x%04x\n", len); + + if (len > sizeof(features)) { + info(udev, "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]; + info(udev, "GET CONFIGURATION: size of features buffer 0x%04x\n", len); + + if (len > sizeof(features)) { + info(udev, "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: + info(udev, "GET CONFIGURATION: feature 'profiles', with %i entries\n", features[i+3] / 4); + feature_profiles(udev, &features[i]+4, features[i+3]); + break; + default: + info(udev, "GET CONFIGURATION: feature 0x%04x , 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; + info(udev, "disk type %02x\n", header[8]); + info(udev, "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]; + info(udev, "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) { + info(udev, "invalid format capacities length\n"); + return -1; + } + + switch(format[8] & 3) { + case 1: + info(udev, "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: + info(udev, "formatted DVD-RAM media inserted\n"); + break; + + case 3: + cd_media = 0; //return no media + info(udev, "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]; + info(udev, "no data in blocks 0 or 16, assuming blank\n"); + } else { + info(udev, "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; + info(udev, "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]; + info(udev, "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]; + info(udev, "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; + + udev_log_init("cdrom_id"); + 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; + if (udev_get_log_priority(udev) < LOG_INFO) + udev_set_log_priority(udev, LOG_INFO); + break; + case 'h': + printf("Usage: cdrom_id [options] \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) { + err(udev, "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) { + info(udev, "unable to open '%s'\n", node); + fprintf(stderr, "unable to open '%s'\n", node); + rc = 1; + goto exit; + } + info(udev, "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) { + info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (lock)\n"); + media_lock(udev, fd, true); + } + + if (unlock && cd_media) { + info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + media_lock(udev, fd, false); + } + + if (eject) { + info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + media_lock(udev, fd, false); + info(udev, "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); + udev_log_close(); + return rc; +} diff --git a/src/collect/.gitignore b/src/collect/.gitignore new file mode 100644 index 0000000000..c30ad6527c --- /dev/null +++ b/src/collect/.gitignore @@ -0,0 +1 @@ +collect diff --git a/src/collect/collect.c b/src/collect/collect.c new file mode 100644 index 0000000000..076fe479e2 --- /dev/null +++ b/src/collect/collect.c @@ -0,0 +1,473 @@ +/* + * Collect variables across events. + * + * usage: collect [--add|--remove] + * + * Adds ID to the list governed by . + * must be part of the ID list . + * If all IDs given by are listed (ie collect has been + * invoked for each ID in ) collect returns 0, the + * number of missing IDs otherwise. + * A negative number is returned on error. + * + * Copyright(C) 2007, Hannes Reinecke + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.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 struct _mate *node_to_mate(struct udev_list_node *node) +{ + char *mate; + + mate = (char *)node; + mate -= offsetof(struct _mate, node); + return (struct _mate *)mate; +} + +static void sig_alrm(int signo) +{ + exit(4); +} + +static void usage(void) +{ + printf("usage: collect [--add|--remove] [--debug] \n" + "\n" + " Adds ID to the list governed by .\n" + " must be part of the list .\n" + " If all IDs given by are listed (ie collect has been\n" + " invoked for each ID in ) 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); + + sprintf(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 -1; + } + 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)); + him->name = strdup(word); + 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 -1; + + 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 -1; + } + buf = tmpbuf; + } + snprintf(buf, strlen(him->name)+2, "%s ", him->name); + write(fd, buf, strlen(buf)); + } + } + + 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), udev_get_run_path(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)); + him->name = malloc(strlen(argv[i]) + 1); + 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/edd_id/.gitignore b/src/edd_id/.gitignore new file mode 100644 index 0000000000..14fb67c634 --- /dev/null +++ b/src/edd_id/.gitignore @@ -0,0 +1 @@ +edd_id diff --git a/src/edd_id/61-persistent-storage-edd.rules b/src/edd_id/61-persistent-storage-edd.rules new file mode 100644 index 0000000000..6b4fb8ecfe --- /dev/null +++ b/src/edd_id/61-persistent-storage-edd.rules @@ -0,0 +1,12 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_storage_edd_end" +SUBSYSTEM!="block", GOTO="persistent_storage_edd_end" +KERNEL!="sd*|hd*|cciss*", GOTO="persistent_storage_edd_end" + +# BIOS Enhanced Disk Device +ENV{DEVTYPE}=="disk", IMPORT{program}="edd_id --export $devnode" +ENV{DEVTYPE}=="disk", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}" +ENV{DEVTYPE}=="partition", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n" + +LABEL="persistent_storage_edd_end" diff --git a/src/edd_id/edd_id.c b/src/edd_id/edd_id.c new file mode 100644 index 0000000000..471ea60533 --- /dev/null +++ b/src/edd_id/edd_id.c @@ -0,0 +1,196 @@ +/* + * edd_id - naming of BIOS disk devices via EDD + * + * Copyright (C) 2005 John Hull + * Copyright (C) 2005 Kay Sievers + * + * 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 . + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +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; + const char *node = NULL; + int i; + int export = 0; + uint32_t disk_id; + uint16_t mbr_valid; + struct dirent *dent; + int disk_fd; + int sysfs_fd; + DIR *dir = NULL; + int rc = 1; + char filename[UTIL_PATH_SIZE]; + char match[UTIL_PATH_SIZE]; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + udev_log_init("edd_id"); + udev_set_log_fn(udev, log_fn); + + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + + if (strcmp(arg, "--export") == 0) { + export = 1; + } else + node = arg; + } + if (node == NULL) { + err(udev, "no node specified\n"); + fprintf(stderr, "no node specified\n"); + goto exit; + } + + /* check for kernel support */ + util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), "/firmware/edd", NULL); + dir = opendir(filename); + if (dir == NULL) { + info(udev, "no kernel EDD support\n"); + fprintf(stderr, "no kernel EDD support\n"); + rc = 2; + goto exit; + } + + disk_fd = open(node, O_RDONLY); + if (disk_fd < 0) { + info(udev, "unable to open '%s'\n", node); + fprintf(stderr, "unable to open '%s'\n", node); + rc = 3; + goto closedir; + } + + /* check for valid MBR signature */ + if (lseek(disk_fd, 510, SEEK_SET) < 0) { + info(udev, "seek to MBR validity failed '%s'\n", node); + rc = 4; + goto close; + } + if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) { + info(udev, "read MBR validity failed '%s'\n", node); + rc = 5; + goto close; + } + if (mbr_valid != 0xAA55) { + fprintf(stderr, "no valid MBR signature '%s'\n", node); + info(udev, "no valid MBR signature '%s'\n", node); + rc=6; + goto close; + } + + /* read EDD signature */ + if (lseek(disk_fd, 440, SEEK_SET) < 0) { + info(udev, "seek to signature failed '%s'\n", node); + rc = 7; + goto close; + } + if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) { + info(udev, "read signature failed '%s'\n", node); + rc = 8; + goto close; + } + /* all zero is invalid */ + info(udev, "read id 0x%08x from '%s'\n", disk_id, node); + if (disk_id == 0) { + fprintf(stderr, "no EDD signature '%s'\n", node); + info(udev, "'%s' signature is zero\n", node); + rc = 9; + goto close; + } + + /* lookup signature in sysfs to determine the name */ + match[0] = '\0'; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char sysfs_id_buf[256]; + uint32_t sysfs_id; + ssize_t size; + + if (dent->d_name[0] == '.') + continue; + + util_strscpyl(filename, sizeof(filename), dent->d_name, "/mbr_signature", NULL); + sysfs_fd = openat(dirfd(dir), filename, O_RDONLY); + if (sysfs_fd < 0) { + info(udev, "unable to open sysfs '%s'\n", filename); + continue; + } + + size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1); + close(sysfs_fd); + if (size <= 0) { + info(udev, "read sysfs '%s' failed\n", filename); + continue; + } + sysfs_id_buf[size] = '\0'; + info(udev, "read '%s' from '%s'\n", sysfs_id_buf, filename); + sysfs_id = strtoul(sysfs_id_buf, NULL, 16); + + /* look for matching value, that appears only once */ + if (disk_id == sysfs_id) { + if (match[0] == '\0') { + /* store id */ + util_strscpy(match, sizeof(match), dent->d_name); + } else { + /* error, same signature for another device */ + info(udev, "'%s' does not have a unique signature\n", node); + fprintf(stderr, "'%s' does not have a unique signature\n", node); + rc = 10; + goto exit; + } + } + } + + if (match[0] != '\0') { + if (export) + printf("ID_EDD=%s\n", match); + else + printf("%s\n", match); + rc = 0; + } + +close: + close(disk_fd); +closedir: + closedir(dir); +exit: + udev_unref(udev); + udev_log_close(); + return rc; +} diff --git a/src/extras/accelerometer/.gitignore b/src/extras/accelerometer/.gitignore deleted file mode 100644 index dddc2204d4..0000000000 --- a/src/extras/accelerometer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -accelerometer diff --git a/src/extras/accelerometer/61-accelerometer.rules b/src/extras/accelerometer/61-accelerometer.rules deleted file mode 100644 index a6a2bfd088..0000000000 --- a/src/extras/accelerometer/61-accelerometer.rules +++ /dev/null @@ -1,3 +0,0 @@ -# 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/src/extras/accelerometer/accelerometer.c b/src/extras/accelerometer/accelerometer.c deleted file mode 100644 index bc9715b264..0000000000 --- a/src/extras/accelerometer/accelerometer.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * 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 - * - * orientation_calc() from the sensorfw package - * Copyright (C) 2009-2010 Nokia Corporation - * Authors: - * Üstün Ergenoglu - * Timo Rongas - * Lihan Guo - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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(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)) - 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] \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; - - udev_log_init("input_id"); - 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; - if (udev_get_log_priority(udev) < LOG_INFO) - udev_set_log_priority(udev, LOG_INFO); - break; - case 'h': - help(); - exit(0); - default: - exit(1); - } - } - - if (argv[optind] == NULL) { - help(); - exit(1); - } - - /* get the device */ - snprintf(devpath, sizeof(devpath), "%s/%s", udev_get_sys_path(udev), 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_children() instead - * when it's available */ - 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; - } - - info(udev, "Opening accelerometer device %s\n", devnode); - test_orientation(udev, dev, devnode); - free(devnode); - - return 0; -} diff --git a/src/extras/ata_id/.gitignore b/src/extras/ata_id/.gitignore deleted file mode 100644 index 77837266e6..0000000000 --- a/src/extras/ata_id/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ata_id diff --git a/src/extras/ata_id/ata_id.c b/src/extras/ata_id/ata_id.c deleted file mode 100644 index 257f494496..0000000000 --- a/src/extras/ata_id/ata_id.c +++ /dev/null @@ -1,726 +0,0 @@ -/* - * ata_id - reads product/serial number from ATA drives - * - * Copyright (C) 2005-2008 Kay Sievers - * Copyright (C) 2009 Lennart Poettering - * Copyright (C) 2009-2010 David Zeuthen - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libudev.h" -#include "libudev-private.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; - - assert(identify != NULL); - assert(dest != NULL); - assert((dest_len & 1) == 0); - - 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; - - assert(out_identify != NULL); - - /* init results */ - ret = -1; - 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; - - udev_log_init("ata_id"); - 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] \n" - " --export print values as environment keys\n" - " --help print this help text\n\n"); - goto exit; - } - } - - node = argv[optind]; - if (node == NULL) { - err(udev, "no node specified\n"); - rc = 1; - goto exit; - } - - fd = open(node, O_RDONLY|O_NONBLOCK); - if (fd < 0) { - err(udev, "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, 6); /* 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) { - if (errno == ENOTTY) { - info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node); - rc = 2; - } else { - err(udev, "HDIO_GET_IDENTITY failed for '%s': %m\n", node); - rc = 3; - } - 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); - udev_log_close(); - return rc; -} diff --git a/src/extras/cdrom_id/.gitignore b/src/extras/cdrom_id/.gitignore deleted file mode 100644 index 7d817ea74e..0000000000 --- a/src/extras/cdrom_id/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cdrom_id diff --git a/src/extras/cdrom_id/60-cdrom_id.rules b/src/extras/cdrom_id/60-cdrom_id.rules deleted file mode 100644 index 6eaf76a72c..0000000000 --- a/src/extras/cdrom_id/60-cdrom_id.rules +++ /dev/null @@ -1,20 +0,0 @@ -# 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/src/extras/cdrom_id/cdrom_id.c b/src/extras/cdrom_id/cdrom_id.c deleted file mode 100644 index f90d52ec9c..0000000000 --- a/src/extras/cdrom_id/cdrom_id.c +++ /dev/null @@ -1,1099 +0,0 @@ -/* - * cdrom_id - optical drive and media information prober - * - * Copyright (C) 2008-2010 Kay Sievers - * - * 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 . - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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", "r"); - 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, char *cmd, int err) -{ - if (err == -1) { - info(udev, "%s failed\n", cmd); - return; - } - info(udev, "%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) - info(udev, "CDROM_CLEAR_OPTIONS, CDO_LOCK failed\n"); - - err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0); - if (err < 0) - info(udev, "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) { - info(udev, "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) { - info(udev, "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) { - info(udev, "not an MMC unit\n"); - return -1; - } - - info(udev, "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: - info(udev, "profile 0x%02x \n", cur_profile); - cd_media = 1; - cd_media_mo = 1; - break; - case 0x08: - info(udev, "profile 0x%02x media_cd_rom\n", cur_profile); - cd_media = 1; - cd_media_cd_rom = 1; - break; - case 0x09: - info(udev, "profile 0x%02x media_cd_r\n", cur_profile); - cd_media = 1; - cd_media_cd_r = 1; - break; - case 0x0a: - info(udev, "profile 0x%02x media_cd_rw\n", cur_profile); - cd_media = 1; - cd_media_cd_rw = 1; - break; - case 0x10: - info(udev, "profile 0x%02x media_dvd_ro\n", cur_profile); - cd_media = 1; - cd_media_dvd_rom = 1; - break; - case 0x11: - info(udev, "profile 0x%02x media_dvd_r\n", cur_profile); - cd_media = 1; - cd_media_dvd_r = 1; - break; - case 0x12: - info(udev, "profile 0x%02x media_dvd_ram\n", cur_profile); - cd_media = 1; - cd_media_dvd_ram = 1; - break; - case 0x13: - info(udev, "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: - info(udev, "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: - info(udev, "profile 0x%02x media_dvd_plus_r\n", cur_profile); - cd_media = 1; - cd_media_dvd_plus_r = 1; - break; - case 0x1A: - info(udev, "profile 0x%02x media_dvd_plus_rw\n", cur_profile); - cd_media = 1; - cd_media_dvd_plus_rw = 1; - break; - case 0x2A: - info(udev, "profile 0x%02x media_dvd_plus_rw_dl\n", cur_profile); - cd_media = 1; - cd_media_dvd_plus_rw_dl = 1; - break; - case 0x2B: - info(udev, "profile 0x%02x media_dvd_plus_r_dl\n", cur_profile); - cd_media = 1; - cd_media_dvd_plus_r_dl = 1; - break; - case 0x40: - info(udev, "profile 0x%02x media_bd\n", cur_profile); - cd_media = 1; - cd_media_bd = 1; - break; - case 0x41: - case 0x42: - info(udev, "profile 0x%02x media_bd_r\n", cur_profile); - cd_media = 1; - cd_media_bd_r = 1; - break; - case 0x43: - info(udev, "profile 0x%02x media_bd_re\n", cur_profile); - cd_media = 1; - cd_media_bd_re = 1; - break; - case 0x50: - info(udev, "profile 0x%02x media_hddvd\n", cur_profile); - cd_media = 1; - cd_media_hddvd = 1; - break; - case 0x51: - info(udev, "profile 0x%02x media_hddvd_r\n", cur_profile); - cd_media = 1; - cd_media_hddvd_r = 1; - break; - case 0x52: - info(udev, "profile 0x%02x media_hddvd_rw\n", cur_profile); - cd_media = 1; - cd_media_hddvd_rw = 1; - break; - default: - info(udev, "profile 0x%02x \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: - info(udev, "profile 0x%02x mo\n", profile); - cd_mo = 1; - break; - case 0x08: - info(udev, "profile 0x%02x cd_rom\n", profile); - cd_cd_rom = 1; - break; - case 0x09: - info(udev, "profile 0x%02x cd_r\n", profile); - cd_cd_r = 1; - break; - case 0x0A: - info(udev, "profile 0x%02x cd_rw\n", profile); - cd_cd_rw = 1; - break; - case 0x10: - info(udev, "profile 0x%02x dvd_rom\n", profile); - cd_dvd_rom = 1; - break; - case 0x12: - info(udev, "profile 0x%02x dvd_ram\n", profile); - cd_dvd_ram = 1; - break; - case 0x13: - case 0x14: - info(udev, "profile 0x%02x dvd_rw\n", profile); - cd_dvd_rw = 1; - break; - case 0x1B: - info(udev, "profile 0x%02x dvd_plus_r\n", profile); - cd_dvd_plus_r = 1; - break; - case 0x1A: - info(udev, "profile 0x%02x dvd_plus_rw\n", profile); - cd_dvd_plus_rw = 1; - break; - case 0x2A: - info(udev, "profile 0x%02x dvd_plus_rw_dl\n", profile); - cd_dvd_plus_rw_dl = 1; - break; - case 0x2B: - info(udev, "profile 0x%02x dvd_plus_r_dl\n", profile); - cd_dvd_plus_r_dl = 1; - break; - case 0x40: - cd_bd = 1; - info(udev, "profile 0x%02x bd\n", profile); - break; - case 0x41: - case 0x42: - cd_bd_r = 1; - info(udev, "profile 0x%02x bd_r\n", profile); - break; - case 0x43: - cd_bd_re = 1; - info(udev, "profile 0x%02x bd_re\n", profile); - break; - case 0x50: - cd_hddvd = 1; - info(udev, "profile 0x%02x hddvd\n", profile); - break; - case 0x51: - cd_hddvd_r = 1; - info(udev, "profile 0x%02x hddvd_r\n", profile); - break; - case 0x52: - cd_hddvd_rw = 1; - info(udev, "profile 0x%02x hddvd_rw\n", profile); - break; - default: - info(udev, "profile 0x%02x \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) { - info(udev, "no current profile, but disc is present; assuming CD-ROM\n"); - cd_media_cd_rom = 1; - return 0; - } else { - info(udev, "no current profile, assuming no media\n"); - return -1; - } - }; - - cd_media = 1; - - if (header[2] & 16) { - cd_media_cd_rw = 1; - info(udev, "profile 0x0a media_cd_rw\n"); - } else if ((header[2] & 3) < 2 && cd_cd_r) { - cd_media_cd_r = 1; - info(udev, "profile 0x09 media_cd_r\n"); - } else { - cd_media_cd_rom = 1; - info(udev, "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) { - info(udev, "drive is pre-MMC2 and does not support 46h get configuration command\n"); - info(udev, "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) { - info(udev, "current profile 0x%02x\n", cur_profile); - feature_profile_media (udev, cur_profile); - ret = 0; /* we have media */ - } else { - info(udev, "no current profile, assuming no media\n"); - } - - len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; - info(udev, "GET CONFIGURATION: size of features buffer 0x%04x\n", len); - - if (len > sizeof(features)) { - info(udev, "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]; - info(udev, "GET CONFIGURATION: size of features buffer 0x%04x\n", len); - - if (len > sizeof(features)) { - info(udev, "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: - info(udev, "GET CONFIGURATION: feature 'profiles', with %i entries\n", features[i+3] / 4); - feature_profiles(udev, &features[i]+4, features[i+3]); - break; - default: - info(udev, "GET CONFIGURATION: feature 0x%04x , 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; - info(udev, "disk type %02x\n", header[8]); - info(udev, "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]; - info(udev, "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) { - info(udev, "invalid format capacities length\n"); - return -1; - } - - switch(format[8] & 3) { - case 1: - info(udev, "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: - info(udev, "formatted DVD-RAM media inserted\n"); - break; - - case 3: - cd_media = 0; //return no media - info(udev, "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]; - info(udev, "no data in blocks 0 or 16, assuming blank\n"); - } else { - info(udev, "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; - info(udev, "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]; - info(udev, "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]; - info(udev, "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; - - udev_log_init("cdrom_id"); - 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; - if (udev_get_log_priority(udev) < LOG_INFO) - udev_set_log_priority(udev, LOG_INFO); - break; - case 'h': - printf("Usage: cdrom_id [options] \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) { - err(udev, "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) { - info(udev, "unable to open '%s'\n", node); - fprintf(stderr, "unable to open '%s'\n", node); - rc = 1; - goto exit; - } - info(udev, "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) { - info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (lock)\n"); - media_lock(udev, fd, true); - } - - if (unlock && cd_media) { - info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); - media_lock(udev, fd, false); - } - - if (eject) { - info(udev, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); - media_lock(udev, fd, false); - info(udev, "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); - udev_log_close(); - return rc; -} diff --git a/src/extras/collect/.gitignore b/src/extras/collect/.gitignore deleted file mode 100644 index c30ad6527c..0000000000 --- a/src/extras/collect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -collect diff --git a/src/extras/collect/collect.c b/src/extras/collect/collect.c deleted file mode 100644 index 076fe479e2..0000000000 --- a/src/extras/collect/collect.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Collect variables across events. - * - * usage: collect [--add|--remove] - * - * Adds ID to the list governed by . - * must be part of the ID list . - * If all IDs given by are listed (ie collect has been - * invoked for each ID in ) collect returns 0, the - * number of missing IDs otherwise. - * A negative number is returned on error. - * - * Copyright(C) 2007, Hannes Reinecke - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libudev.h" -#include "libudev-private.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 struct _mate *node_to_mate(struct udev_list_node *node) -{ - char *mate; - - mate = (char *)node; - mate -= offsetof(struct _mate, node); - return (struct _mate *)mate; -} - -static void sig_alrm(int signo) -{ - exit(4); -} - -static void usage(void) -{ - printf("usage: collect [--add|--remove] [--debug] \n" - "\n" - " Adds ID to the list governed by .\n" - " must be part of the list .\n" - " If all IDs given by are listed (ie collect has been\n" - " invoked for each ID in ) 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); - - sprintf(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 -1; - } - 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)); - him->name = strdup(word); - 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 -1; - - 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 -1; - } - buf = tmpbuf; - } - snprintf(buf, strlen(him->name)+2, "%s ", him->name); - write(fd, buf, strlen(buf)); - } - } - - 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), udev_get_run_path(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)); - him->name = malloc(strlen(argv[i]) + 1); - 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/extras/edd_id/.gitignore b/src/extras/edd_id/.gitignore deleted file mode 100644 index 14fb67c634..0000000000 --- a/src/extras/edd_id/.gitignore +++ /dev/null @@ -1 +0,0 @@ -edd_id diff --git a/src/extras/edd_id/61-persistent-storage-edd.rules b/src/extras/edd_id/61-persistent-storage-edd.rules deleted file mode 100644 index 6b4fb8ecfe..0000000000 --- a/src/extras/edd_id/61-persistent-storage-edd.rules +++ /dev/null @@ -1,12 +0,0 @@ -# do not edit this file, it will be overwritten on update - -ACTION=="remove", GOTO="persistent_storage_edd_end" -SUBSYSTEM!="block", GOTO="persistent_storage_edd_end" -KERNEL!="sd*|hd*|cciss*", GOTO="persistent_storage_edd_end" - -# BIOS Enhanced Disk Device -ENV{DEVTYPE}=="disk", IMPORT{program}="edd_id --export $devnode" -ENV{DEVTYPE}=="disk", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}" -ENV{DEVTYPE}=="partition", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n" - -LABEL="persistent_storage_edd_end" diff --git a/src/extras/edd_id/edd_id.c b/src/extras/edd_id/edd_id.c deleted file mode 100644 index 471ea60533..0000000000 --- a/src/extras/edd_id/edd_id.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * edd_id - naming of BIOS disk devices via EDD - * - * Copyright (C) 2005 John Hull - * Copyright (C) 2005 Kay Sievers - * - * 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 . - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libudev.h" -#include "libudev-private.h" - -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; - const char *node = NULL; - int i; - int export = 0; - uint32_t disk_id; - uint16_t mbr_valid; - struct dirent *dent; - int disk_fd; - int sysfs_fd; - DIR *dir = NULL; - int rc = 1; - char filename[UTIL_PATH_SIZE]; - char match[UTIL_PATH_SIZE]; - - udev = udev_new(); - if (udev == NULL) - goto exit; - - udev_log_init("edd_id"); - udev_set_log_fn(udev, log_fn); - - for (i = 1 ; i < argc; i++) { - char *arg = argv[i]; - - if (strcmp(arg, "--export") == 0) { - export = 1; - } else - node = arg; - } - if (node == NULL) { - err(udev, "no node specified\n"); - fprintf(stderr, "no node specified\n"); - goto exit; - } - - /* check for kernel support */ - util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), "/firmware/edd", NULL); - dir = opendir(filename); - if (dir == NULL) { - info(udev, "no kernel EDD support\n"); - fprintf(stderr, "no kernel EDD support\n"); - rc = 2; - goto exit; - } - - disk_fd = open(node, O_RDONLY); - if (disk_fd < 0) { - info(udev, "unable to open '%s'\n", node); - fprintf(stderr, "unable to open '%s'\n", node); - rc = 3; - goto closedir; - } - - /* check for valid MBR signature */ - if (lseek(disk_fd, 510, SEEK_SET) < 0) { - info(udev, "seek to MBR validity failed '%s'\n", node); - rc = 4; - goto close; - } - if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) { - info(udev, "read MBR validity failed '%s'\n", node); - rc = 5; - goto close; - } - if (mbr_valid != 0xAA55) { - fprintf(stderr, "no valid MBR signature '%s'\n", node); - info(udev, "no valid MBR signature '%s'\n", node); - rc=6; - goto close; - } - - /* read EDD signature */ - if (lseek(disk_fd, 440, SEEK_SET) < 0) { - info(udev, "seek to signature failed '%s'\n", node); - rc = 7; - goto close; - } - if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) { - info(udev, "read signature failed '%s'\n", node); - rc = 8; - goto close; - } - /* all zero is invalid */ - info(udev, "read id 0x%08x from '%s'\n", disk_id, node); - if (disk_id == 0) { - fprintf(stderr, "no EDD signature '%s'\n", node); - info(udev, "'%s' signature is zero\n", node); - rc = 9; - goto close; - } - - /* lookup signature in sysfs to determine the name */ - match[0] = '\0'; - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char sysfs_id_buf[256]; - uint32_t sysfs_id; - ssize_t size; - - if (dent->d_name[0] == '.') - continue; - - util_strscpyl(filename, sizeof(filename), dent->d_name, "/mbr_signature", NULL); - sysfs_fd = openat(dirfd(dir), filename, O_RDONLY); - if (sysfs_fd < 0) { - info(udev, "unable to open sysfs '%s'\n", filename); - continue; - } - - size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1); - close(sysfs_fd); - if (size <= 0) { - info(udev, "read sysfs '%s' failed\n", filename); - continue; - } - sysfs_id_buf[size] = '\0'; - info(udev, "read '%s' from '%s'\n", sysfs_id_buf, filename); - sysfs_id = strtoul(sysfs_id_buf, NULL, 16); - - /* look for matching value, that appears only once */ - if (disk_id == sysfs_id) { - if (match[0] == '\0') { - /* store id */ - util_strscpy(match, sizeof(match), dent->d_name); - } else { - /* error, same signature for another device */ - info(udev, "'%s' does not have a unique signature\n", node); - fprintf(stderr, "'%s' does not have a unique signature\n", node); - rc = 10; - goto exit; - } - } - } - - if (match[0] != '\0') { - if (export) - printf("ID_EDD=%s\n", match); - else - printf("%s\n", match); - rc = 0; - } - -close: - close(disk_fd); -closedir: - closedir(dir); -exit: - udev_unref(udev); - udev_log_close(); - return rc; -} diff --git a/src/extras/floppy/.gitignore b/src/extras/floppy/.gitignore deleted file mode 100644 index 939f625a4a..0000000000 --- a/src/extras/floppy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -create_floppy_devices diff --git a/src/extras/floppy/60-floppy.rules b/src/extras/floppy/60-floppy.rules deleted file mode 100644 index 53e4a9e59a..0000000000 --- a/src/extras/floppy/60-floppy.rules +++ /dev/null @@ -1,4 +0,0 @@ -# do not edit this file, it will be overwritten on update - -SUBSYSTEM=="block", KERNEL=="fd[0-9]", ACTION=="add", ATTRS{cmos}=="?*", ENV{CMOS_TYPE}="$attr{cmos}", \ - RUN+="create_floppy_devices -c -t $env{CMOS_TYPE} -m %M -M 0660 -G floppy $root/%k" diff --git a/src/extras/floppy/create_floppy_devices.c b/src/extras/floppy/create_floppy_devices.c deleted file mode 100644 index f71ef0d809..0000000000 --- a/src/extras/floppy/create_floppy_devices.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Create all possible floppy device based on the CMOS type. - * Based upon code from drivers/block/floppy.c - * - * Copyright(C) 2005, SUSE Linux Products GmbH - * - * Author: Hannes Reinecke - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libudev.h" -#include "libudev-private.h" - -static char *table[] = { - "", "d360", "h1200", "u360", "u720", "h360", "h720", - "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410", - "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743", - "h880", "u1040", "u1120", "h1600", "u1760", "u1920", - "u3200", "u3520", "u3840", "u1840", "u800", "u1600", - NULL -}; - -static int t360[] = { 1, 0 }; -static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 }; -static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30, 0 }; -static int *table_sup[] = { NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in }; - -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; - char *dev; - char *devname; - char node[64]; - int type = 0, i, fdnum, c; - int major = 2, minor; - uid_t uid = 0; - gid_t gid = 0; - mode_t mode = 0660; - int create_nodes = 0; - int print_nodes = 0; - int is_err = 0; - - udev = udev_new(); - if (udev == NULL) - goto exit; - - udev_log_init("create_floppy_devices"); - udev_set_log_fn(udev, log_fn); - udev_selinux_init(udev); - - while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) { - switch (c) { - case 'c': - create_nodes = 1; - break; - case 'd': - print_nodes = 1; - break; - case 'U': - uid = util_lookup_user(udev, optarg); - break; - case 'G': - gid = util_lookup_group(udev, optarg); - break; - case 'M': - mode = strtol(optarg, NULL, 0); - mode = mode & 0666; - break; - case 'm': - major = strtol(optarg, NULL, 0); - break; - case 't': - type = strtol(optarg, NULL, 0); - break; - default: - is_err++; - break; - } - } - - if (is_err || optind >= argc) { - printf("Usage: %s [OPTION] device\n" - " -c create\n" - " -d debug\n" - " -m Major number\n" - " -t floppy type number\n" - " -U device node user ownership\n" - " -G device node group owner\n" - " -M device node mode\n" - "\n", argv[0]); - return 1; - } - - dev = argv[optind]; - devname = strrchr(dev, '/'); - if (devname != NULL) - devname = &devname[1]; - else - devname = dev; - if (strncmp(devname, "fd", 2) != 0) { - fprintf(stderr,"Device '%s' is not a floppy device\n", dev); - return 1; - } - - fdnum = strtol(&devname[2], NULL, 10); - if (fdnum < 0 || fdnum > 7) { - fprintf(stderr,"Floppy device number %d out of range (0-7)\n", fdnum); - return 1; - } - if (fdnum > 3) - fdnum += 124; - - if (major < 1) { - fprintf(stderr,"Invalid major number %d\n", major); - return 1; - } - - if (type < 0 || type >= (int) ARRAY_SIZE(table_sup)) { - fprintf(stderr,"Invalid CMOS type %d\n", type); - return 1; - } - - if (type == 0) - return 0; - - i = 0; - while (table_sup[type][i]) { - sprintf(node, "%s%s", dev, table[table_sup[type][i]]); - minor = (table_sup[type][i] << 2) + fdnum; - if (print_nodes) - printf("%s b %.4o %d %d\n", node, mode, major, minor); - if (create_nodes) { - unlink(node); - udev_selinux_setfscreatecon(udev, node, S_IFBLK | mode); - mknod(node, S_IFBLK | mode, makedev(major,minor)); - udev_selinux_resetfscreatecon(udev); - chown(node, uid, gid); - chmod(node, S_IFBLK | mode); - } - i++; - } - - udev_selinux_exit(udev); - udev_unref(udev); - udev_log_close(); -exit: - return 0; -} diff --git a/src/extras/gudev/.gitignore b/src/extras/gudev/.gitignore deleted file mode 100644 index d20fa523e4..0000000000 --- a/src/extras/gudev/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -gtk-doc.make -docs/version.xml -gudev-1.0.pc -gudevenumtypes.c -gudevenumtypes.h -gudevmarshal.c -gudevmarshal.h -GUdev-1.0.gir -GUdev-1.0.typelib diff --git a/src/extras/gudev/COPYING b/src/extras/gudev/COPYING deleted file mode 100644 index da97db2bd0..0000000000 --- a/src/extras/gudev/COPYING +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - 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. - - 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. - - 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. - - 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. - - 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. - - 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. - - 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 - - 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. - - - Copyright (C) - - 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 St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/src/extras/gudev/docs/.gitignore b/src/extras/gudev/docs/.gitignore deleted file mode 100644 index 8eada6d409..0000000000 --- a/src/extras/gudev/docs/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -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.stamp -html/* -xml/* -tmpl/* -*.stamp diff --git a/src/extras/gudev/docs/Makefile.am b/src/extras/gudev/docs/Makefile.am deleted file mode 100644 index 3512197660..0000000000 --- a/src/extras/gudev/docs/Makefile.am +++ /dev/null @@ -1,106 +0,0 @@ -## 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 - -# 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=--sgml-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= - -# 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/extras/gudev/*.h -CFILE_GLOB=$(top_srcdir)/src/extras/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= - -# 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= - -# 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 = \ - $(DBUS_GLIB_CFLAGS) \ - $(GLIB_CFLAGS) \ - -I$(top_srcdir)/src/extras/gudev \ - -I$(top_builddir)/src/extras/gudev - -GTKDOC_LIBS = \ - $(GLIB_LIBS) \ - $(top_builddir)/src/extras/gudev/libgudev-1.0.la - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/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 $(srcsrc) -#TESTS = $(GTKDOC_CHECK) -endif diff --git a/src/extras/gudev/docs/gudev-docs.xml b/src/extras/gudev/docs/gudev-docs.xml deleted file mode 100644 index f876c3bc05..0000000000 --- a/src/extras/gudev/docs/gudev-docs.xml +++ /dev/null @@ -1,93 +0,0 @@ - - -]> - - - GUDev Reference Manual - For GUdev version &version; - - - David - Zeuthen - -
- davidz@redhat.com -
-
-
- - Bastien - Nocera - -
- hadess@hadess.net -
-
-
-
- - - 2011 - The GUDev Authors - - - - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free - Documentation License, Version 1.1 or any later - version published by the Free Software Foundation with no - Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. You may obtain a copy of the GNU Free - Documentation License from the Free Software - Foundation by visiting their Web site or by writing - to: - -
- The Free Software Foundation, Inc., - 59 Temple Place - Suite 330, - Boston, MA 02111-1307, - USA -
-
- - - Many of the names used by companies to distinguish their - products and services are claimed as trademarks. Where those - names appear in any freedesktop.org documentation, and those - trademarks are made aware to the members of the - freedesktop.org Project, the names have been printed in caps - or initial caps. - -
-
- - - API Reference - - - This part presents the class and function reference for the - libgudev library. - - - - - - - - - Object Hierarchy - - - - Index - - - Index of new symbols in 165 - - - -
diff --git a/src/extras/gudev/docs/gudev-sections.txt b/src/extras/gudev/docs/gudev-sections.txt deleted file mode 100644 index 213e1a7465..0000000000 --- a/src/extras/gudev/docs/gudev-sections.txt +++ /dev/null @@ -1,113 +0,0 @@ -
-gudevclient -GUdevClient -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 - -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 - -GUdevClientPrivate -
- -
-gudevdevice -GUdevDevice -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 - -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 - -GUdevDevicePrivate -
- -
-gudevenumerator -GUdevEnumerator -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 - -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 - -GUdevEnumeratorPrivate -
- -
-gudevmarshal - -g_udev_marshal_VOID__STRING_OBJECT -
- -
-gudevenumtypes - -G_TYPE_UDEV_DEVICE_TYPE -g_udev_device_type_get_type -
diff --git a/src/extras/gudev/docs/gudev.types b/src/extras/gudev/docs/gudev.types deleted file mode 100644 index a89857a04d..0000000000 --- a/src/extras/gudev/docs/gudev.types +++ /dev/null @@ -1,4 +0,0 @@ -g_udev_device_type_get_type -g_udev_device_get_type -g_udev_client_get_type -g_udev_enumerator_get_type diff --git a/src/extras/gudev/docs/version.xml.in b/src/extras/gudev/docs/version.xml.in deleted file mode 100644 index d78bda9342..0000000000 --- a/src/extras/gudev/docs/version.xml.in +++ /dev/null @@ -1 +0,0 @@ -@VERSION@ diff --git a/src/extras/gudev/gjs-example.js b/src/extras/gudev/gjs-example.js deleted file mode 100755 index 5586fd6a61..0000000000 --- a/src/extras/gudev/gjs-example.js +++ /dev/null @@ -1,75 +0,0 @@ -#!/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/extras/gudev/gudev-1.0.pc.in b/src/extras/gudev/gudev-1.0.pc.in deleted file mode 100644 index 058262d767..0000000000 --- a/src/extras/gudev/gudev-1.0.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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/extras/gudev/gudev.h b/src/extras/gudev/gudev.h deleted file mode 100644 index a313460817..0000000000 --- a/src/extras/gudev/gudev.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 1 -#include -#include -#include -#include -#include -#include -#undef _GUDEV_INSIDE_GUDEV_H - -#endif /* __G_UDEV_H__ */ diff --git a/src/extras/gudev/gudevclient.c b/src/extras/gudev/gudevclient.c deleted file mode 100644 index 2b94102ac5..0000000000 --- a/src/extras/gudev/gudevclient.c +++ /dev/null @@ -1,527 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008-2010 David Zeuthen - * - * 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 -#include - -#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 - * sysfs filesystem) and the udev daemon (through a - * tmpfs 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 - * thread-default main loop - * 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 - * thread-default main loop - * 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/extras/gudev/gudevclient.h b/src/extras/gudev/gudevclient.h deleted file mode 100644 index b425d03d48..0000000000 --- a/src/extras/gudev/gudevclient.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_CLIENT_H__ -#define __G_UDEV_CLIENT_H__ - -#include - -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/extras/gudev/gudevdevice.c b/src/extras/gudev/gudevdevice.c deleted file mode 100644 index 62a26f99b7..0000000000 --- a/src/extras/gudev/gudevdevice.c +++ /dev/null @@ -1,963 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 -#include - -#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 /dev) 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/extras/gudev/gudevdevice.h b/src/extras/gudev/gudevdevice.h deleted file mode 100644 index d4873bad0f..0000000000 --- a/src/extras/gudev/gudevdevice.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_DEVICE_H__ -#define __G_UDEV_DEVICE_H__ - -#include - -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/extras/gudev/gudevenumerator.c b/src/extras/gudev/gudevenumerator.c deleted file mode 100644 index db09074625..0000000000 --- a/src/extras/gudev/gudevenumerator.c +++ /dev/null @@ -1,431 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008-2010 David Zeuthen - * - * 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 -#include - -#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/extras/gudev/gudevenumerator.h b/src/extras/gudev/gudevenumerator.h deleted file mode 100644 index 3fddccf573..0000000000 --- a/src/extras/gudev/gudevenumerator.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008-2010 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_ENUMERATOR_H__ -#define __G_UDEV_ENUMERATOR_H__ - -#include - -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/extras/gudev/gudevenums.h b/src/extras/gudev/gudevenums.h deleted file mode 100644 index c3a0aa8747..0000000000 --- a/src/extras/gudev/gudevenums.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_ENUMS_H__ -#define __G_UDEV_ENUMS_H__ - -#include - -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/extras/gudev/gudevenumtypes.c.template b/src/extras/gudev/gudevenumtypes.c.template deleted file mode 100644 index fc30b39e2e..0000000000 --- a/src/extras/gudev/gudevenumtypes.c.template +++ /dev/null @@ -1,39 +0,0 @@ -/*** BEGIN file-header ***/ -#include - -/*** 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/extras/gudev/gudevenumtypes.h.template b/src/extras/gudev/gudevenumtypes.h.template deleted file mode 100644 index d0ab3393e6..0000000000 --- a/src/extras/gudev/gudevenumtypes.h.template +++ /dev/null @@ -1,24 +0,0 @@ -/*** BEGIN file-header ***/ -#ifndef __GUDEV_ENUM_TYPES_H__ -#define __GUDEV_ENUM_TYPES_H__ - -#include - -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/extras/gudev/gudevmarshal.list b/src/extras/gudev/gudevmarshal.list deleted file mode 100644 index 7e665999e8..0000000000 --- a/src/extras/gudev/gudevmarshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID:STRING,OBJECT diff --git a/src/extras/gudev/gudevprivate.h b/src/extras/gudev/gudevprivate.h deleted file mode 100644 index 8866f52b88..0000000000 --- a/src/extras/gudev/gudevprivate.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_PRIVATE_H__ -#define __G_UDEV_PRIVATE_H__ - -#include - -#include - -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/extras/gudev/gudevtypes.h b/src/extras/gudev/gudevtypes.h deleted file mode 100644 index 888482783d..0000000000 --- a/src/extras/gudev/gudevtypes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2008 David Zeuthen - * - * 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 can be included directly, this file may disappear or change contents." -#endif - -#ifndef __G_UDEV_TYPES_H__ -#define __G_UDEV_TYPES_H__ - -#include -#include - -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/extras/gudev/seed-example-enum.js b/src/extras/gudev/seed-example-enum.js deleted file mode 100755 index 66206ad806..0000000000 --- a/src/extras/gudev/seed-example-enum.js +++ /dev/null @@ -1,38 +0,0 @@ -#!/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/extras/gudev/seed-example.js b/src/extras/gudev/seed-example.js deleted file mode 100755 index e2ac324d23..0000000000 --- a/src/extras/gudev/seed-example.js +++ /dev/null @@ -1,72 +0,0 @@ -#!/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/extras/keymap/.gitignore b/src/extras/keymap/.gitignore deleted file mode 100644 index 01d62e2b6e..0000000000 --- a/src/extras/keymap/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -keyboard-force-release.sh -keymap -keys-from-name.gperf -keys-from-name.h -keys-to-name.h -keys.txt diff --git a/src/extras/keymap/95-keyboard-force-release.rules b/src/extras/keymap/95-keyboard-force-release.rules deleted file mode 100644 index 79a1bc1cc4..0000000000 --- a/src/extras/keymap/95-keyboard-force-release.rules +++ /dev/null @@ -1,53 +0,0 @@ -# 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}=="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*|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" - -ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO Si 1848+u|AMILO Xi 2428", 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}=="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/extras/keymap/95-keymap.rules b/src/extras/keymap/95-keymap.rules deleted file mode 100644 index 26de03dcc7..0000000000 --- a/src/extras/keymap/95-keymap.rules +++ /dev/null @@ -1,169 +0,0 @@ -# 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}=="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 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" - - -# -# 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[02]* 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}=="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}=="*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" -# 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}=="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/extras/keymap/README.keymap.txt b/src/extras/keymap/README.keymap.txt deleted file mode 100644 index 52d50ed2de..0000000000 --- a/src/extras/keymap/README.keymap.txt +++ /dev/null @@ -1,101 +0,0 @@ -= 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 - - fdi2rules.py:: convert hal keymap FDIs into udev rules and key map files - (Please note that this is far from perfect, since the mapping between fdi and - udev rules is not straightforward, and impossible in some cases.) - -== 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 . diff --git a/src/extras/keymap/check-keymaps.sh b/src/extras/keymap/check-keymaps.sh deleted file mode 100755 index 423699b5a8..0000000000 --- a/src/extras/keymap/check-keymaps.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# check that all key names in keymaps/* are known in -# and that all key maps listed in the rules are valid and present in -# Makefile.am -SRCDIR=${1:-.} -KEYLIST=${2:-src/extras/keymap/keys.txt} -KEYMAPS_DIR=$SRCDIR/src/extras/keymap/keymaps -RULES=$SRCDIR/src/extras/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 src/extras/keymap/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 "src/extras/keymap/keymaps/$m\>" $SRCDIR/Makefile.am || { - echo "ERROR: map file $m is not added to Makefile.am" >&2 - exit 1 - } -done diff --git a/src/extras/keymap/findkeyboards b/src/extras/keymap/findkeyboards deleted file mode 100755 index 9ce27429b2..0000000000 --- a/src/extras/keymap/findkeyboards +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh -e -# Find "real" keyboard devices and print their device path. -# Author: Martin Pitt -# -# 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/extras/keymap/force-release-maps/common-volume-keys b/src/extras/keymap/force-release-maps/common-volume-keys deleted file mode 100644 index 3a7654d735..0000000000 --- a/src/extras/keymap/force-release-maps/common-volume-keys +++ /dev/null @@ -1,3 +0,0 @@ -0xa0 #mute -0xae #volume down -0xb0 #volume up diff --git a/src/extras/keymap/force-release-maps/dell-touchpad b/src/extras/keymap/force-release-maps/dell-touchpad deleted file mode 100644 index 18e9bdee66..0000000000 --- a/src/extras/keymap/force-release-maps/dell-touchpad +++ /dev/null @@ -1 +0,0 @@ -0x9E diff --git a/src/extras/keymap/force-release-maps/hp-other b/src/extras/keymap/force-release-maps/hp-other deleted file mode 100644 index 6621370095..0000000000 --- a/src/extras/keymap/force-release-maps/hp-other +++ /dev/null @@ -1,3 +0,0 @@ -# list of scancodes (hex or decimal), optional comment -0xd8 # Touchpad off -0xd9 # Touchpad on diff --git a/src/extras/keymap/force-release-maps/samsung-other b/src/extras/keymap/force-release-maps/samsung-other deleted file mode 100644 index c51123a0b6..0000000000 --- a/src/extras/keymap/force-release-maps/samsung-other +++ /dev/null @@ -1,10 +0,0 @@ -# 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/src/extras/keymap/keyboard-force-release.sh.in b/src/extras/keymap/keyboard-force-release.sh.in deleted file mode 100755 index dd040cebc3..0000000000 --- a/src/extras/keymap/keyboard-force-release.sh.in +++ /dev/null @@ -1,22 +0,0 @@ -#!@rootprefix@/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="@pkglibexecdir@/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/extras/keymap/keymap.c b/src/extras/keymap/keymap.c deleted file mode 100644 index 92ec67b3a6..0000000000 --- a/src/extras/keymap/keymap.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * keymap - dump keymap of an evdev device or set a new keymap from a file - * - * Based on keyfuzz by Lennart Poettering - * Adapted for udev-extras by Martin Pitt - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const struct key* lookup_key (const char *str, unsigned int len); - -#include "keys-from-name.h" -#include "keys-to-name.h" - -#define MAX_SCANCODES 1024 - -static int evdev_open(const char *dev) -{ - int fd; - char fn[PATH_MAX]; - - if (strncmp(dev, "/dev", 4) != 0) { - 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, int scancode, int e) -{ - int codes[2]; - - codes[0] = scancode; - if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) { - if (e && errno == EINVAL) { - return -2; - } else { - fprintf(stderr, "EVIOCGKEYCODE: %m\n"); - return -1; - } - } - return codes[1]; -} - -static int evdev_set_keycode(int fd, int scancode, int keycode) -{ - int codes[2]; - - codes[0] = scancode; - codes[1] = 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]; - int scancode, 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; - int scancode, 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; - goto fail; - } - - if (evdev_set_keycode(fd, scancode, new_keycode) < 0) { - r = -1; - goto fail; - } - - if (new_keycode != old_keycode) - fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n", - scancode, new_keycode, old_keycode); - } -fail: - 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(uint32_t 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; - uint32_t 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); -} - -static void help(int error) -{ - const char* h = "Usage: keymap []\n" - " keymap scancode keyname [...]\n" - " keymap -i \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, "r"); - 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]; - snprintf(keymap_path, sizeof(keymap_path), "%s%s", SYSCONFDIR "/udev/keymaps/", filearg); - FILE *f = fopen(keymap_path, "r"); - if (f) { - merge_table(fd, f); - } else { - snprintf(keymap_path, sizeof(keymap_path), "%s%s", PKGLIBEXECDIR "/keymaps/", filearg); - f = fopen(keymap_path, "r"); - 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/extras/keymap/keymaps/acer b/src/extras/keymap/keymaps/acer deleted file mode 100644 index 4e7c297dea..0000000000 --- a/src/extras/keymap/keymaps/acer +++ /dev/null @@ -1,22 +0,0 @@ -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/src/extras/keymap/keymaps/acer-aspire_5720 b/src/extras/keymap/keymaps/acer-aspire_5720 deleted file mode 100644 index 1496d63a52..0000000000 --- a/src/extras/keymap/keymaps/acer-aspire_5720 +++ /dev/null @@ -1,4 +0,0 @@ -0x84 bluetooth # sent when bluetooth module missing, and key pressed -0x92 media # acer arcade -0xD4 bluetooth # bluetooth on -0xD9 bluetooth # bluetooth off diff --git a/src/extras/keymap/keymaps/acer-aspire_5920g b/src/extras/keymap/keymaps/acer-aspire_5920g deleted file mode 100644 index 633c4e854c..0000000000 --- a/src/extras/keymap/keymaps/acer-aspire_5920g +++ /dev/null @@ -1,5 +0,0 @@ -0x8A media -0x92 media -0xA6 setup -0xB2 www -0xD9 bluetooth # (toggle) on-to-off diff --git a/src/extras/keymap/keymaps/acer-aspire_6920 b/src/extras/keymap/keymaps/acer-aspire_6920 deleted file mode 100644 index 699c954b4e..0000000000 --- a/src/extras/keymap/keymaps/acer-aspire_6920 +++ /dev/null @@ -1,5 +0,0 @@ -0xD9 bluetooth # (toggle) on-to-off -0x92 media -0x9E back -0x83 rewind -0x89 fastforward diff --git a/src/extras/keymap/keymaps/acer-aspire_8930 b/src/extras/keymap/keymaps/acer-aspire_8930 deleted file mode 100644 index fb27bfb4f5..0000000000 --- a/src/extras/keymap/keymaps/acer-aspire_8930 +++ /dev/null @@ -1,5 +0,0 @@ -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/src/extras/keymap/keymaps/acer-travelmate_c300 b/src/extras/keymap/keymaps/acer-travelmate_c300 deleted file mode 100644 index bfef4cf868..0000000000 --- a/src/extras/keymap/keymaps/acer-travelmate_c300 +++ /dev/null @@ -1,5 +0,0 @@ -0x67 f24 # FIXME: rotate screen -0x68 up -0x69 down -0x6B fn -0x6C screenlock # FIXME: lock tablet device/buttons diff --git a/src/extras/keymap/keymaps/asus b/src/extras/keymap/keymaps/asus deleted file mode 100644 index 2a5995f982..0000000000 --- a/src/extras/keymap/keymaps/asus +++ /dev/null @@ -1,3 +0,0 @@ -0xED volumeup -0xEE volumedown -0xEF mute diff --git a/src/extras/keymap/keymaps/compaq-e_evo b/src/extras/keymap/keymaps/compaq-e_evo deleted file mode 100644 index 5fbc573aa4..0000000000 --- a/src/extras/keymap/keymaps/compaq-e_evo +++ /dev/null @@ -1,4 +0,0 @@ -0xA3 www # I key -0x9A search -0x9E email -0x9F homepage diff --git a/src/extras/keymap/keymaps/dell b/src/extras/keymap/keymaps/dell deleted file mode 100644 index 4f907b3eef..0000000000 --- a/src/extras/keymap/keymaps/dell +++ /dev/null @@ -1,29 +0,0 @@ -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/src/extras/keymap/keymaps/dell-latitude-xt2 b/src/extras/keymap/keymaps/dell-latitude-xt2 deleted file mode 100644 index 39872f559d..0000000000 --- a/src/extras/keymap/keymaps/dell-latitude-xt2 +++ /dev/null @@ -1,4 +0,0 @@ -0x9B up # tablet rocker up -0x9E enter # tablet rocker press -0x9F back # tablet back -0xA3 down # tablet rocker down diff --git a/src/extras/keymap/keymaps/everex-xt5000 b/src/extras/keymap/keymaps/everex-xt5000 deleted file mode 100644 index 4823a832f5..0000000000 --- a/src/extras/keymap/keymaps/everex-xt5000 +++ /dev/null @@ -1,7 +0,0 @@ -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/src/extras/keymap/keymaps/fujitsu-amilo_li_2732 b/src/extras/keymap/keymaps/fujitsu-amilo_li_2732 deleted file mode 100644 index 9b8b36a170..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-amilo_li_2732 +++ /dev/null @@ -1,3 +0,0 @@ -0xD9 brightnessdown # Fn+F8 brightness down -0xEF brightnessup # Fn+F9 brightness up -0xA9 switchvideomode # Fn+F10 Cycle between available video outputs diff --git a/src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 b/src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 deleted file mode 100644 index f7b0c52444..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-amilo_pa_2548 +++ /dev/null @@ -1,3 +0,0 @@ -0xE0 volumedown -0xE1 volumeup -0xE5 prog1 diff --git a/src/extras/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 b/src/extras/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 deleted file mode 100644 index d2e38cbb23..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 +++ /dev/null @@ -1,4 +0,0 @@ -0xA5 help # Fn-F1 -0xA9 switchvideomode # Fn-F3 -0xD9 brightnessdown # Fn-F8 -0xE0 brightnessup # Fn-F9 diff --git a/src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 b/src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 deleted file mode 100644 index 43e3199d59..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-amilo_pro_v3205 +++ /dev/null @@ -1,2 +0,0 @@ -0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock -0xF7 switchvideomode # Fn+F3 diff --git a/src/extras/keymap/keymaps/fujitsu-amilo_si_1520 b/src/extras/keymap/keymaps/fujitsu-amilo_si_1520 deleted file mode 100644 index 1419bd9b5e..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-amilo_si_1520 +++ /dev/null @@ -1,6 +0,0 @@ -0xE1 wlan -0xF3 wlan -0xEE brightnessdown -0xE0 brightnessup -0xE2 bluetooth -0xF7 video diff --git a/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v5 b/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v5 deleted file mode 100644 index d3d056b366..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v5 +++ /dev/null @@ -1,4 +0,0 @@ -0xA9 switchvideomode -0xD9 brightnessdown -0xDF sleep -0xEF brightnessup diff --git a/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v6 b/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v6 deleted file mode 100644 index 52c70c50cb..0000000000 --- a/src/extras/keymap/keymaps/fujitsu-esprimo_mobile_v6 +++ /dev/null @@ -1,2 +0,0 @@ -0xCE brightnessup -0xEF brightnessdown diff --git a/src/extras/keymap/keymaps/genius-slimstar-320 b/src/extras/keymap/keymaps/genius-slimstar-320 deleted file mode 100644 index d0a3656dd8..0000000000 --- a/src/extras/keymap/keymaps/genius-slimstar-320 +++ /dev/null @@ -1,35 +0,0 @@ -# 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/src/extras/keymap/keymaps/hewlett-packard b/src/extras/keymap/keymaps/hewlett-packard deleted file mode 100644 index 4461fa2ce5..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard +++ /dev/null @@ -1,12 +0,0 @@ -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/src/extras/keymap/keymaps/hewlett-packard-2510p_2530p b/src/extras/keymap/keymaps/hewlett-packard-2510p_2530p deleted file mode 100644 index 41ad2e9b5a..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-2510p_2530p +++ /dev/null @@ -1,2 +0,0 @@ -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on diff --git a/src/extras/keymap/keymaps/hewlett-packard-compaq_elitebook b/src/extras/keymap/keymaps/hewlett-packard-compaq_elitebook deleted file mode 100644 index 42007c5483..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-compaq_elitebook +++ /dev/null @@ -1,2 +0,0 @@ -0x88 presentation -0xD9 help # I key (high keycode: "info") diff --git a/src/extras/keymap/keymaps/hewlett-packard-pavilion b/src/extras/keymap/keymaps/hewlett-packard-pavilion deleted file mode 100644 index 3d3cefc8e6..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-pavilion +++ /dev/null @@ -1,3 +0,0 @@ -0x88 media # FIXME: quick play -0xD8 f23 # touchpad off -0xD9 f22 # touchpad on diff --git a/src/extras/keymap/keymaps/hewlett-packard-presario-2100 b/src/extras/keymap/keymaps/hewlett-packard-presario-2100 deleted file mode 100644 index 1df39dcbd2..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-presario-2100 +++ /dev/null @@ -1,3 +0,0 @@ -0xF0 help -0xF1 screenlock -0xF3 search diff --git a/src/extras/keymap/keymaps/hewlett-packard-tablet b/src/extras/keymap/keymaps/hewlett-packard-tablet deleted file mode 100644 index d19005ab90..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-tablet +++ /dev/null @@ -1,6 +0,0 @@ -0x82 prog2 # Funny Key -0x83 prog1 # Q -0x84 tab -0x85 esc -0x86 pageup -0x87 pagedown diff --git a/src/extras/keymap/keymaps/hewlett-packard-tx2 b/src/extras/keymap/keymaps/hewlett-packard-tx2 deleted file mode 100644 index 36a690fcf6..0000000000 --- a/src/extras/keymap/keymaps/hewlett-packard-tx2 +++ /dev/null @@ -1,3 +0,0 @@ -0xC2 media -0xD8 f23 # Toggle touchpad button on tx2 (OFF) -0xD9 f22 # Toggle touchpad button on tx2 (ON) diff --git a/src/extras/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint b/src/extras/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint deleted file mode 100644 index 027e50bf88..0000000000 --- a/src/extras/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint +++ /dev/null @@ -1,7 +0,0 @@ -0x900f0 screenlock -0x900f1 wlan -0x900f2 switchvideomode -0x900f3 suspend -0x900f4 brightnessup -0x900f5 brightnessdown -0x900f8 zoom diff --git a/src/extras/keymap/keymaps/inventec-symphony_6.0_7.0 b/src/extras/keymap/keymaps/inventec-symphony_6.0_7.0 deleted file mode 100644 index 4a8b4ba5a7..0000000000 --- a/src/extras/keymap/keymaps/inventec-symphony_6.0_7.0 +++ /dev/null @@ -1,2 +0,0 @@ -0xF3 prog2 -0xF4 prog1 diff --git a/src/extras/keymap/keymaps/lenovo-3000 b/src/extras/keymap/keymaps/lenovo-3000 deleted file mode 100644 index 5bd165654a..0000000000 --- a/src/extras/keymap/keymaps/lenovo-3000 +++ /dev/null @@ -1,5 +0,0 @@ -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/src/extras/keymap/keymaps/lenovo-ideapad b/src/extras/keymap/keymaps/lenovo-ideapad deleted file mode 100644 index fc339839f2..0000000000 --- a/src/extras/keymap/keymaps/lenovo-ideapad +++ /dev/null @@ -1,8 +0,0 @@ -# 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/src/extras/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/src/extras/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint deleted file mode 100644 index 47e8846a68..0000000000 --- a/src/extras/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint +++ /dev/null @@ -1,13 +0,0 @@ -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/src/extras/keymap/keymaps/lenovo-thinkpad_x200_tablet b/src/extras/keymap/keymaps/lenovo-thinkpad_x200_tablet deleted file mode 100644 index 31ea3b2c70..0000000000 --- a/src/extras/keymap/keymaps/lenovo-thinkpad_x200_tablet +++ /dev/null @@ -1,6 +0,0 @@ -0x5D menu -0x63 fn -0x66 screenlock -0x67 cyclewindows # bezel circular arrow -0x68 setup # bezel setup / menu -0x6c direction # rotate screen diff --git a/src/extras/keymap/keymaps/lenovo-thinkpad_x6_tablet b/src/extras/keymap/keymaps/lenovo-thinkpad_x6_tablet deleted file mode 100644 index 6fd16b5662..0000000000 --- a/src/extras/keymap/keymaps/lenovo-thinkpad_x6_tablet +++ /dev/null @@ -1,8 +0,0 @@ -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/src/extras/keymap/keymaps/lg-x110 b/src/extras/keymap/keymaps/lg-x110 deleted file mode 100644 index ba08cba3fe..0000000000 --- a/src/extras/keymap/keymaps/lg-x110 +++ /dev/null @@ -1,12 +0,0 @@ -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/src/extras/keymap/keymaps/logitech-wave b/src/extras/keymap/keymaps/logitech-wave deleted file mode 100644 index caa5d5d310..0000000000 --- a/src/extras/keymap/keymaps/logitech-wave +++ /dev/null @@ -1,16 +0,0 @@ -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/src/extras/keymap/keymaps/logitech-wave-cordless b/src/extras/keymap/keymaps/logitech-wave-cordless deleted file mode 100644 index a10dad5e4d..0000000000 --- a/src/extras/keymap/keymaps/logitech-wave-cordless +++ /dev/null @@ -1,15 +0,0 @@ -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/src/extras/keymap/keymaps/logitech-wave-pro-cordless b/src/extras/keymap/keymaps/logitech-wave-pro-cordless deleted file mode 100644 index e7aa02206c..0000000000 --- a/src/extras/keymap/keymaps/logitech-wave-pro-cordless +++ /dev/null @@ -1,12 +0,0 @@ -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/src/extras/keymap/keymaps/maxdata-pro_7000 b/src/extras/keymap/keymaps/maxdata-pro_7000 deleted file mode 100644 index c0e4f77af4..0000000000 --- a/src/extras/keymap/keymaps/maxdata-pro_7000 +++ /dev/null @@ -1,9 +0,0 @@ -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/src/extras/keymap/keymaps/medion-fid2060 b/src/extras/keymap/keymaps/medion-fid2060 deleted file mode 100644 index 5a76c76799..0000000000 --- a/src/extras/keymap/keymaps/medion-fid2060 +++ /dev/null @@ -1,2 +0,0 @@ -0x6B channeldown # Thottle Down -0x6D channelup # Thottle Up diff --git a/src/extras/keymap/keymaps/medionnb-a555 b/src/extras/keymap/keymaps/medionnb-a555 deleted file mode 100644 index c3b5dfa60b..0000000000 --- a/src/extras/keymap/keymaps/medionnb-a555 +++ /dev/null @@ -1,4 +0,0 @@ -0x63 www # N button -0x66 prog1 # link 1 button -0x67 email # envelope button -0x69 prog2 # link 2 button diff --git a/src/extras/keymap/keymaps/micro-star b/src/extras/keymap/keymaps/micro-star deleted file mode 100644 index 4a438698ed..0000000000 --- a/src/extras/keymap/keymaps/micro-star +++ /dev/null @@ -1,13 +0,0 @@ -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/src/extras/keymap/keymaps/module-asus-w3j b/src/extras/keymap/keymaps/module-asus-w3j deleted file mode 100644 index 773e0b3e82..0000000000 --- a/src/extras/keymap/keymaps/module-asus-w3j +++ /dev/null @@ -1,11 +0,0 @@ -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/src/extras/keymap/keymaps/module-ibm b/src/extras/keymap/keymaps/module-ibm deleted file mode 100644 index a92dfa2506..0000000000 --- a/src/extras/keymap/keymaps/module-ibm +++ /dev/null @@ -1,16 +0,0 @@ -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/src/extras/keymap/keymaps/module-lenovo b/src/extras/keymap/keymaps/module-lenovo deleted file mode 100644 index 8e38883091..0000000000 --- a/src/extras/keymap/keymaps/module-lenovo +++ /dev/null @@ -1,17 +0,0 @@ -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/src/extras/keymap/keymaps/module-sony b/src/extras/keymap/keymaps/module-sony deleted file mode 100644 index 7c000131d1..0000000000 --- a/src/extras/keymap/keymaps/module-sony +++ /dev/null @@ -1,8 +0,0 @@ -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/src/extras/keymap/keymaps/module-sony-old b/src/extras/keymap/keymaps/module-sony-old deleted file mode 100644 index 596a34258a..0000000000 --- a/src/extras/keymap/keymaps/module-sony-old +++ /dev/null @@ -1,2 +0,0 @@ -0x06 battery -0x07 mute diff --git a/src/extras/keymap/keymaps/module-sony-vgn b/src/extras/keymap/keymaps/module-sony-vgn deleted file mode 100644 index c8ba001516..0000000000 --- a/src/extras/keymap/keymaps/module-sony-vgn +++ /dev/null @@ -1,8 +0,0 @@ -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/src/extras/keymap/keymaps/olpc-xo b/src/extras/keymap/keymaps/olpc-xo deleted file mode 100644 index 34434a121d..0000000000 --- a/src/extras/keymap/keymaps/olpc-xo +++ /dev/null @@ -1,74 +0,0 @@ -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/src/extras/keymap/keymaps/onkyo b/src/extras/keymap/keymaps/onkyo deleted file mode 100644 index ee864ade4d..0000000000 --- a/src/extras/keymap/keymaps/onkyo +++ /dev/null @@ -1,14 +0,0 @@ -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/src/extras/keymap/keymaps/oqo-model2 b/src/extras/keymap/keymaps/oqo-model2 deleted file mode 100644 index b7f4851abe..0000000000 --- a/src/extras/keymap/keymaps/oqo-model2 +++ /dev/null @@ -1,5 +0,0 @@ -0x8E wlan -0xF0 switchvideomode -0xF1 mute -0xF2 volumedown -0xF3 volumeup diff --git a/src/extras/keymap/keymaps/samsung-other b/src/extras/keymap/keymaps/samsung-other deleted file mode 100644 index 3ac0c2f10c..0000000000 --- a/src/extras/keymap/keymaps/samsung-other +++ /dev/null @@ -1,14 +0,0 @@ -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/src/extras/keymap/keymaps/samsung-sq1us b/src/extras/keymap/keymaps/samsung-sq1us deleted file mode 100644 index ea2141ef84..0000000000 --- a/src/extras/keymap/keymaps/samsung-sq1us +++ /dev/null @@ -1,7 +0,0 @@ -0xD4 menu -0xD8 f1 -0xD9 f10 -0xD6 f3 -0xD7 f9 -0xE4 f5 -0xEE f11 diff --git a/src/extras/keymap/keymaps/samsung-sx20s b/src/extras/keymap/keymaps/samsung-sx20s deleted file mode 100644 index 9d954ee415..0000000000 --- a/src/extras/keymap/keymaps/samsung-sx20s +++ /dev/null @@ -1,4 +0,0 @@ -0x74 mute -0x75 mute -0x77 f22 # Touchpad on -0x79 f23 # Touchpad off diff --git a/src/extras/keymap/keymaps/toshiba-satellite_a100 b/src/extras/keymap/keymaps/toshiba-satellite_a100 deleted file mode 100644 index 22007be71b..0000000000 --- a/src/extras/keymap/keymaps/toshiba-satellite_a100 +++ /dev/null @@ -1,2 +0,0 @@ -0xA4 stopcd -0xB2 www diff --git a/src/extras/keymap/keymaps/toshiba-satellite_a110 b/src/extras/keymap/keymaps/toshiba-satellite_a110 deleted file mode 100644 index 1429409351..0000000000 --- a/src/extras/keymap/keymaps/toshiba-satellite_a110 +++ /dev/null @@ -1,10 +0,0 @@ -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/src/extras/keymap/keymaps/toshiba-satellite_m30x b/src/extras/keymap/keymaps/toshiba-satellite_m30x deleted file mode 100644 index ae8e34941b..0000000000 --- a/src/extras/keymap/keymaps/toshiba-satellite_m30x +++ /dev/null @@ -1,6 +0,0 @@ -0xef brightnessdown -0xd9 brightnessup -0xee screenlock -0x93 media -0x9e f22 #touchpad_enable -0x9f f23 #touchpad_disable diff --git a/src/extras/keymap/keymaps/zepto-znote b/src/extras/keymap/keymaps/zepto-znote deleted file mode 100644 index cf72fda47b..0000000000 --- a/src/extras/keymap/keymaps/zepto-znote +++ /dev/null @@ -1,11 +0,0 @@ -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/src/extras/mtd_probe/.gitignore b/src/extras/mtd_probe/.gitignore deleted file mode 100644 index 82b8ab501f..0000000000 --- a/src/extras/mtd_probe/.gitignore +++ /dev/null @@ -1 +0,0 @@ -mtd_probe diff --git a/src/extras/mtd_probe/75-probe_mtd.rules b/src/extras/mtd_probe/75-probe_mtd.rules deleted file mode 100644 index c0e0839785..0000000000 --- a/src/extras/mtd_probe/75-probe_mtd.rules +++ /dev/null @@ -1,8 +0,0 @@ -# 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/src/extras/mtd_probe/mtd_probe.c b/src/extras/mtd_probe/mtd_probe.c deleted file mode 100644 index 1aa08d3851..0000000000 --- a/src/extras/mtd_probe/mtd_probe.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char** argv) -{ - if (argc != 2) { - printf("usage: mtd_probe /dev/mtd[n]\n"); - return 1; - } - - int mtd_fd = open(argv[1], O_RDONLY); - if (mtd_fd == -1) { - perror("open"); - exit(-1); - } - - mtd_info_t mtd_info; - int 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/extras/mtd_probe/mtd_probe.h b/src/extras/mtd_probe/mtd_probe.h deleted file mode 100644 index 2a37ede578..0000000000 --- a/src/extras/mtd_probe/mtd_probe.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 - -/* 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/extras/mtd_probe/probe_smartmedia.c b/src/extras/mtd_probe/probe_smartmedia.c deleted file mode 100644 index b3cdefc633..0000000000 --- a/src/extras/mtd_probe/probe_smartmedia.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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) -{ - char* cis_buffer = malloc(SM_SECTOR_SIZE); - - if (!cis_buffer) - return; - - if (info->type != MTD_NANDFLASH) - goto exit; - - int sector_size = info->writesize; - int block_size = info->erasesize; - int size_in_megs = info->size / (1024 * 1024); - int spare_count; - - - 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; - } - - - int offset; - int cis_found = 0; - - 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/extras/qemu/42-qemu-usb.rules b/src/extras/qemu/42-qemu-usb.rules deleted file mode 100644 index a4e3864714..0000000000 --- a/src/extras/qemu/42-qemu-usb.rules +++ /dev/null @@ -1,13 +0,0 @@ -# -# 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" diff --git a/src/extras/rule_generator/75-cd-aliases-generator.rules b/src/extras/rule_generator/75-cd-aliases-generator.rules deleted file mode 100644 index e6da0101d6..0000000000 --- a/src/extras/rule_generator/75-cd-aliases-generator.rules +++ /dev/null @@ -1,9 +0,0 @@ -# these rules generate rules for the /dev/{cdrom,dvd,...} symlinks - -# the "path" of usb/ieee1394 devices changes frequently, use "id" -ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb|ieee1394", ENV{ID_CDROM}=="?*", ENV{GENERATED}!="?*", \ - PROGRAM="write_cd_rules by-id", SYMLINK+="%c", GOTO="persistent_cd_end" - -ACTION=="add", SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", ENV{GENERATED}!="?*", PROGRAM="write_cd_rules", SYMLINK+="%c" - -LABEL="persistent_cd_end" diff --git a/src/extras/rule_generator/75-persistent-net-generator.rules b/src/extras/rule_generator/75-persistent-net-generator.rules deleted file mode 100644 index 4f80573478..0000000000 --- a/src/extras/rule_generator/75-persistent-net-generator.rules +++ /dev/null @@ -1,102 +0,0 @@ -# do not edit this file, it will be overwritten on update - -# these rules generate rules for persistent network device naming -# -# variables used to communicate: -# MATCHADDR MAC address used for the match -# MATCHID bus_id used for the match -# MATCHDRV driver name used for the match -# MATCHIFTYPE interface type match -# COMMENT comment to add to the generated rule -# INTERFACE_NAME requested name supplied by external tool -# INTERFACE_NEW new interface name returned by rule writer - -ACTION!="add", GOTO="persistent_net_generator_end" -SUBSYSTEM!="net", GOTO="persistent_net_generator_end" - -# ignore the interface if a name has already been set -NAME=="?*", GOTO="persistent_net_generator_end" - -# device name whitelist -KERNEL!="eth*|ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end" - -# ignore Xen virtual interfaces -SUBSYSTEMS=="xen", GOTO="persistent_net_generator_end" - -# read MAC address -ENV{MATCHADDR}="$attr{address}" - -# match interface type -ENV{MATCHIFTYPE}="$attr{type}" - -# ignore KVM virtual interfaces -ENV{MATCHADDR}=="52:54:00:*", GOTO="persistent_net_generator_end" -# ignore VMWare virtual interfaces -ENV{MATCHADDR}=="00:0c:29:*|00:50:56:*", GOTO="persistent_net_generator_end" -# ignore Hyper-V virtual interfaces -ENV{MATCHADDR}=="00:15:5d:*", GOTO="persistent_net_generator_end" - -# These vendors are known to violate the local MAC address assignment scheme -# Interlan, DEC (UNIBUS or QBUS), Apollo, Cisco, Racal-Datacom -ENV{MATCHADDR}=="02:07:01:*", GOTO="globally_administered_whitelist" -# 3Com -ENV{MATCHADDR}=="02:60:60:*", GOTO="globally_administered_whitelist" -# 3Com IBM PC; Imagen; Valid; Cisco; Apple -ENV{MATCHADDR}=="02:60:8c:*", GOTO="globally_administered_whitelist" -# Intel -ENV{MATCHADDR}=="02:a0:c9:*", GOTO="globally_administered_whitelist" -# Olivetti -ENV{MATCHADDR}=="02:aa:3c:*", GOTO="globally_administered_whitelist" -# CMC Masscomp; Silicon Graphics; Prime EXL -ENV{MATCHADDR}=="02:cf:1f:*", GOTO="globally_administered_whitelist" -# Prominet Corporation Gigabit Ethernet Switch -ENV{MATCHADDR}=="02:e0:3b:*", GOTO="globally_administered_whitelist" -# BTI (Bus-Tech, Inc.) IBM Mainframes -ENV{MATCHADDR}=="02:e6:d3:*", GOTO="globally_administered_whitelist" -# Realtek -ENV{MATCHADDR}=="52:54:00:*", GOTO="globally_administered_whitelist" -# Novell 2000 -ENV{MATCHADDR}=="52:54:4c:*", GOTO="globally_administered_whitelist" -# Realtec -ENV{MATCHADDR}=="52:54:ab:*", GOTO="globally_administered_whitelist" -# Kingston Technologies -ENV{MATCHADDR}=="e2:0c:0f:*", GOTO="globally_administered_whitelist" -# Xensource -ENV{MATCHADDR}=="00:16:3e:*", GOTO="globally_administered_whitelist" - -# match interface dev_id -ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}" - -# do not use "locally administered" MAC address -ENV{MATCHADDR}=="?[2367abef]:*", ENV{MATCHADDR}="" - -# do not use empty address -ENV{MATCHADDR}=="00:00:00:00:00:00", ENV{MATCHADDR}="" - -LABEL="globally_administered_whitelist" - -# build comment line for generated rule: -SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device} ($driver)" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="?*", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct} ($driver)" -SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id} ($driver)" -SUBSYSTEMS=="ieee1394", ENV{COMMENT}="Firewire device $attr{host_id})" - -# ibmveth likes to use "locally administered" MAC addresses -DRIVERS=="ibmveth", ENV{MATCHADDR}="$attr{address}", ENV{COMMENT}="ibmveth ($id)" - -# S/390 uses id matches only, do not use MAC address match -SUBSYSTEMS=="ccwgroup", ENV{COMMENT}="S/390 $driver device at $id", ENV{MATCHID}="$id", ENV{MATCHDRV}="$driver", ENV{MATCHADDR}="" - -# see if we got enough data to create a rule -ENV{MATCHADDR}=="", ENV{MATCHID}=="", ENV{INTERFACE_NAME}=="", GOTO="persistent_net_generator_end" - -# default comment -ENV{COMMENT}=="", ENV{COMMENT}="net device ($attr{driver})" - -# write rule -DRIVERS=="?*", IMPORT{program}="write_net_rules" - -# rename interface if needed -ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}" - -LABEL="persistent_net_generator_end" diff --git a/src/extras/rule_generator/rule_generator.functions b/src/extras/rule_generator/rule_generator.functions deleted file mode 100644 index 2eec1b6abf..0000000000 --- a/src/extras/rule_generator/rule_generator.functions +++ /dev/null @@ -1,113 +0,0 @@ -# functions used by the udev rule generator - -# Copyright (C) 2006 Marco d'Itri - -# 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 . - -PATH='/usr/bin:/bin:/usr/sbin:/sbin' - -# Read a single line from file $1 in the $DEVPATH directory. -# The function must not return an error even if the file does not exist. -sysread() { - local file="$1" - [ -e "/sys$DEVPATH/$file" ] || return 0 - local value - read value < "/sys$DEVPATH/$file" || return 0 - echo "$value" -} - -sysreadlink() { - local file="$1" - [ -e "/sys$DEVPATH/$file" ] || return 0 - readlink -f /sys$DEVPATH/$file 2> /dev/null || true -} - -# Return true if a directory is writeable. -writeable() { - if ln -s test-link $1/.is-writeable 2> /dev/null; then - rm -f $1/.is-writeable - return 0 - else - return 1 - fi -} - -# Create a lock file for the current rules file. -lock_rules_file() { - RUNDIR=$(udevadm info --run) - [ -e "$RUNDIR" ] || return 0 - - RULES_LOCK="$RUNDIR/.lock-${RULES_FILE##*/}" - - retry=30 - while ! mkdir $RULES_LOCK 2> /dev/null; do - if [ $retry -eq 0 ]; then - echo "Cannot lock $RULES_FILE!" >&2 - exit 2 - fi - sleep 1 - retry=$(($retry - 1)) - done -} - -unlock_rules_file() { - [ "$RULES_LOCK" ] || return 0 - rmdir $RULES_LOCK || true -} - -# Choose the real rules file if it is writeable or a temporary file if not. -# Both files should be checked later when looking for existing rules. -choose_rules_file() { - RUNDIR=$(udevadm info --run) - local tmp_rules_file="$RUNDIR/tmp-rules--${RULES_FILE##*/}" - [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 - - if writeable ${RULES_FILE%/*}; then - RO_RULES_FILE='/dev/null' - else - RO_RULES_FILE=$RULES_FILE - RULES_FILE=$tmp_rules_file - fi -} - -# Return the name of the first free device. -raw_find_next_available() { - local links="$1" - - local basename=${links%%[ 0-9]*} - local max=-1 - for name in $links; do - local num=${name#$basename} - [ "$num" ] || num=0 - [ $num -gt $max ] && max=$num - done - - local max=$(($max + 1)) - # "name0" actually is just "name" - [ $max -eq 0 ] && return - echo "$max" -} - -# Find all rules matching a key (with action) and a pattern. -find_all_rules() { - local key="$1" - local linkre="$2" - local match="$3" - - local search='.*[[:space:],]'"$key"'"('"$linkre"')".*' - echo $(sed -n -r -e 's/^#.*//' -e "${match}s/${search}/\1/p" \ - $RO_RULES_FILE \ - $([ -e $RULES_FILE ] && echo $RULES_FILE) \ - 2>/dev/null) -} diff --git a/src/extras/rule_generator/write_cd_rules b/src/extras/rule_generator/write_cd_rules deleted file mode 100644 index 645b9cd521..0000000000 --- a/src/extras/rule_generator/write_cd_rules +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/sh -e - -# This script is run if an optical drive lacks a rule for persistent naming. -# -# It adds symlinks for optical drives based on the device class determined -# by cdrom_id and used ID_PATH to identify the device. - -# (C) 2006 Marco d'Itri -# -# 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 . - -# debug, if UDEV_LOG= -if [ -n "$UDEV_LOG" ]; then - if [ "$UDEV_LOG" -ge 7 ]; then - set -x - fi -fi - -RULES_FILE="/etc/udev/rules.d/70-persistent-cd.rules" - -. /lib/udev/rule_generator.functions - -find_next_available() { - raw_find_next_available "$(find_all_rules 'SYMLINK\+=' "$1")" -} - -write_rule() { - local match="$1" - local link="$2" - local comment="$3" - - { - if [ "$PRINT_HEADER" ]; then - PRINT_HEADER= - echo "# This file was automatically generated by the $0" - echo "# program, run by the cd-aliases-generator.rules rules file." - echo "#" - echo "# You can modify it, as long as you keep each rule on a single" - echo "# line, and set the \$GENERATED variable." - echo "" - fi - - [ "$comment" ] && echo "# $comment" - echo "$match, SYMLINK+=\"$link\", ENV{GENERATED}=\"1\"" - } >> $RULES_FILE - SYMLINKS="$SYMLINKS $link" -} - -if [ -z "$DEVPATH" ]; then - echo "Missing \$DEVPATH." >&2 - exit 1 -fi -if [ -z "$ID_CDROM" ]; then - echo "$DEVPATH is not a CD reader." >&2 - exit 1 -fi - -if [ "$1" ]; then - METHOD="$1" -else - METHOD='by-path' -fi - -case "$METHOD" in - by-path) - if [ -z "$ID_PATH" ]; then - echo "$DEVPATH not supported by path_id. by-id may work." >&2 - exit 1 - fi - RULE="ENV{ID_PATH}==\"$ID_PATH\"" - ;; - - by-id) - if [ "$ID_SERIAL" ]; then - RULE="ENV{ID_SERIAL}==\"$ID_SERIAL\"" - elif [ "$ID_MODEL" -a "$ID_REVISION" ]; then - RULE="ENV{ID_MODEL}==\"$ID_MODEL\", ENV{ID_REVISION}==\"$ID_REVISION\"" - else - echo "$DEVPATH not supported by ata_id. by-path may work." >&2 - exit 1 - fi - ;; - - *) - echo "Invalid argument (must be either by-path or by-id)." >&2 - exit 1 - ;; -esac - -# Prevent concurrent processes from modifying the file at the same time. -lock_rules_file - -# Check if the rules file is writeable. -choose_rules_file - -link_num=$(find_next_available 'cdrom[0-9]*') - -match="SUBSYSTEM==\"block\", ENV{ID_CDROM}==\"?*\", $RULE" - -comment="$ID_MODEL ($ID_PATH)" - - write_rule "$match" "cdrom$link_num" "$comment" -[ "$ID_CDROM_CD_R" -o "$ID_CDROM_CD_RW" ] && \ - write_rule "$match" "cdrw$link_num" -[ "$ID_CDROM_DVD" ] && \ - write_rule "$match" "dvd$link_num" -[ "$ID_CDROM_DVD_R" -o "$ID_CDROM_DVD_RW" -o "$ID_CDROM_DVD_RAM" ] && \ - write_rule "$match" "dvdrw$link_num" -echo >> $RULES_FILE - -unlock_rules_file - -echo $SYMLINKS - -exit 0 diff --git a/src/extras/rule_generator/write_net_rules b/src/extras/rule_generator/write_net_rules deleted file mode 100644 index bcea4b09dc..0000000000 --- a/src/extras/rule_generator/write_net_rules +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/sh -e - -# This script is run to create persistent network device naming rules -# based on properties of the device. -# If the interface needs to be renamed, INTERFACE_NEW= will be printed -# on stdout to allow udev to IMPORT it. - -# variables used to communicate: -# MATCHADDR MAC address used for the match -# MATCHID bus_id used for the match -# MATCHDEVID dev_id used for the match -# MATCHDRV driver name used for the match -# MATCHIFTYPE interface type match -# COMMENT comment to add to the generated rule -# INTERFACE_NAME requested name supplied by external tool -# INTERFACE_NEW new interface name returned by rule writer - -# Copyright (C) 2006 Marco d'Itri -# Copyright (C) 2007 Kay Sievers -# -# 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 . - -# debug, if UDEV_LOG= -if [ -n "$UDEV_LOG" ]; then - if [ "$UDEV_LOG" -ge 7 ]; then - set -x - fi -fi - -RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules' - -. /lib/udev/rule_generator.functions - -interface_name_taken() { - local value="$(find_all_rules 'NAME=' $INTERFACE)" - if [ "$value" ]; then - return 0 - else - return 1 - fi -} - -find_next_available() { - raw_find_next_available "$(find_all_rules 'NAME=' "$1")" -} - -write_rule() { - local match="$1" - local name="$2" - local comment="$3" - - { - if [ "$PRINT_HEADER" ]; then - PRINT_HEADER= - echo "# This file was automatically generated by the $0" - echo "# program, run by the persistent-net-generator.rules rules file." - echo "#" - echo "# You can modify it, as long as you keep each rule on a single" - echo "# line, and change only the value of the NAME= key." - fi - - echo "" - [ "$comment" ] && echo "# $comment" - echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\"" - } >> $RULES_FILE -} - -if [ -z "$INTERFACE" ]; then - echo "missing \$INTERFACE" >&2 - exit 1 -fi - -# Prevent concurrent processes from modifying the file at the same time. -lock_rules_file - -# Check if the rules file is writeable. -choose_rules_file - -# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces -if [ "$MATCHADDR" ]; then - match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\"" -fi - -if [ "$MATCHDRV" ]; then - match="$match, DRIVERS==\"$MATCHDRV\"" -fi - -if [ "$MATCHDEVID" ]; then - match="$match, ATTR{dev_id}==\"$MATCHDEVID\"" -fi - -if [ "$MATCHID" ]; then - match="$match, KERNELS==\"$MATCHID\"" -fi - -if [ "$MATCHIFTYPE" ]; then - match="$match, ATTR{type}==\"$MATCHIFTYPE\"" -fi - -if [ -z "$match" ]; then - echo "missing valid match" >&2 - unlock_rules_file - exit 1 -fi - -basename=${INTERFACE%%[0-9]*} -match="$match, KERNEL==\"$basename*\"" - -if [ "$INTERFACE_NAME" ]; then - # external tools may request a custom name - COMMENT="$COMMENT (custom name provided by external tool)" - if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then - INTERFACE=$INTERFACE_NAME; - echo "INTERFACE_NEW=$INTERFACE" - fi -else - # if a rule using the current name already exists, find a new name - if interface_name_taken; then - INTERFACE="$basename$(find_next_available "$basename[0-9]*")" - # prevent INTERFACE from being "eth" instead of "eth0" - [ "$INTERFACE" = "${INTERFACE%%[ \[\]0-9]*}" ] && INTERFACE=${INTERFACE}0 - echo "INTERFACE_NEW=$INTERFACE" - fi -fi - -write_rule "$match" "$INTERFACE" "$COMMENT" - -unlock_rules_file - -exit 0 diff --git a/src/extras/scsi_id/.gitignore b/src/extras/scsi_id/.gitignore deleted file mode 100644 index 10e9ae743c..0000000000 --- a/src/extras/scsi_id/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -scsi_id -scsi_id.8 -scsi_id_version.h diff --git a/src/extras/scsi_id/README b/src/extras/scsi_id/README deleted file mode 100644 index 9cfe73991c..0000000000 --- a/src/extras/scsi_id/README +++ /dev/null @@ -1,4 +0,0 @@ -scsi_id - generate a SCSI unique identifier for a given SCSI device - -Please send questions, comments or patches to or -. diff --git a/src/extras/scsi_id/scsi.h b/src/extras/scsi_id/scsi.h deleted file mode 100644 index c423cac574..0000000000 --- a/src/extras/scsi_id/scsi.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 - -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 ) 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/extras/scsi_id/scsi_id.8 b/src/extras/scsi_id/scsi_id.8 deleted file mode 100644 index 0d4dba9149..0000000000 --- a/src/extras/scsi_id/scsi_id.8 +++ /dev/null @@ -1,119 +0,0 @@ -.TH SCSI_ID 8 "December 2003" "" "Linux Administrator's Manual" -.SH NAME -scsi_id \- retrieve and generate a unique SCSI identifier -.SH SYNOPSIS -.BI scsi_id -[\fIoptions\fP] -.SH "DESCRIPTION" -.B scsi_id -queries a SCSI device via the SCSI INQUIRY vital product data (VPD) page 0x80 or -0x83 and uses the resulting data to generate a value that is unique across -all SCSI devices that properly support page 0x80 or page 0x83. - -If a result is generated it is sent to standard output, and the program -exits with a zero value. If no identifier is output, the program exits -with a non\-zero value. - -\fBscsi_id\fP is primarily for use by other utilities such as \fBudev\fP -that require a unique SCSI identifier. - -By default all devices are assumed black listed, the \fB\-\-whitelisted\fP option must -be specified on the command line or in the config file for any useful -behaviour. - -SCSI commands are sent directly to the device via the SG_IO ioctl -interface. - -In order to generate unique values for either page 0x80 or page 0x83, the -serial numbers or world wide names are prefixed as follows. - -Identifiers based on page 0x80 are prefixed by the character 'S', the SCSI -vendor, the SCSI product (model) and then the the serial number returned -by page 0x80. For example: - -.sp -.nf -# /usr/lib/udev/scsi_id \-\-page=0x80 \-\-whitelisted \-\-device=/dev/sda -SIBM 3542 1T05078453 -.fi -.P - -Identifiers based on page 0x83 are prefixed by the identifier type -followed by the page 0x83 identifier. For example, a device with a NAA -(Name Address Authority) type of 3 (also in this case the page 0x83 -identifier starts with the NAA value of 6): - -.sp -.nf -# /usr/lib/udev/scsi_id \-\-page=0x83 \-\-whitelisted \-\-device=/dev/sda -3600a0b80000b174b000000d63efc5c8c -.fi -.P - -.SH OPTIONS -.TP -.BI \-\-blacklisted -The default behaviour \- treat the device as black listed, and do nothing -unless a white listed device is found in the scsi_id config\-file. -.TP -.BI \-\-device=\| device\^ -Send SG_IO commands to \fBdevice\fP, such as \fB/dev/sdc\fP. -.TP -.BI \-\-config=\| config\-file -Read configuration and black/white list entries from -.B config\-file -rather than the default -.B /etc/scsi_id.config -file. -.TP -.BI \-\-whitelisted -Treat the device as white listed. The \fB\-\-whitelisted\fP option must be specified -on the command line or in the scsi_id configuration file for -.B scsi_id -to generate any output. -.TP -.BI \-\-page=\| 0x80 | 0x83 | pre-spc3-83 -Use SCSI INQUIRY VPD page code 0x80, 0x83, or pre-spc3-83. -.sp -The default -behaviour is to query the available VPD pages, and use page 0x83 if found, -else page 0x80 if found, else nothing. -.sp -Page pre-spc3-83 should only be utilized for those scsi devices which -are not compliant with the SPC-2 or SPC-3 format for page 83. While this -option is used for older model 4, 5, and 6 EMC Symmetrix devices, its -use with SPC-2 or SPC-3 compliant devices will fallback to the page 83 -format supported by these devices. -.TP -.BI \-\-replace-whitespace -Reformat the output : replace all whitespaces by underscores. -.TP -.BI \-\-export -Export all data in KEY= format used to import in other programs. -.TP -.BI \-\-verbose -Generate verbose debugging output. -.TP -.BI \-\-version -Display version number and exit. -.RE - -.SH "FILES" -.nf -.ft B -.ft -.TP -\fI/etc/scsi_id.config\fP -Configuration of black/white list entries and per device options: -# one config per line, short match strings match longer strings -# vendor=string[,model=string],options= -vendor="ATA",options=-p 0x80 -.RE -.fi -.LP -.SH "SEE ALSO" -.BR udev (7) -.SH AUTHORS -Developed by Patrick Mansfield based on SCSI ID -source included in earlier linux 2.5 kernels, sg_utils source, and SCSI -specifications. diff --git a/src/extras/scsi_id/scsi_id.c b/src/extras/scsi_id/scsi_id.c deleted file mode 100644 index 9bb0d7f538..0000000000 --- a/src/extras/scsi_id/scsi_id.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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] = SYSCONFDIR "/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; - 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 char *quote_string = "\"\n"; - static char *comma_string = ",\n"; - char *val; - 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; - - dbg(udev, "vendor='%s'; model='%s'\n", vendor, model); - fd = fopen(config_file, "r"); - if (fd == NULL) { - dbg(udev, "can't open %s\n", config_file); - if (errno == ENOENT) { - return 1; - } else { - err(udev, "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); - err(udev, "can't allocate memory\n"); - return -1; - } - - *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') { - err(udev, "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; - - dbg(udev, "lineno %d: '%s'\n", lineno, buf); - str1 = strsep(&buf, "="); - if (str1 && strcasecmp(str1, "VENDOR") == 0) { - str1 = get_value(&buf); - if (!str1) { - retval = -1; - break; - } - vendor_in = str1; - - str1 = strsep(&buf, "="); - if (str1 && strcasecmp(str1, "MODEL") == 0) { - str1 = get_value(&buf); - if (!str1) { - retval = -1; - break; - } - model_in = str1; - str1 = strsep(&buf, "="); - } - } - - if (str1 && strcasecmp(str1, "OPTIONS") == 0) { - str1 = get_value(&buf); - if (!str1) { - retval = -1; - break; - } - options_in = str1; - } - dbg(udev, "config file line %d:\n" - " vendor '%s'; model '%s'; options '%s'\n", - lineno, vendor_in, model_in, options_in); - /* - * Only allow: [vendor=foo[,model=bar]]options=stuff - */ - if (!options_in || (!vendor_in && model_in)) { - err(udev, "Error parsing config file line %d '%s'\n", lineno, buffer); - retval = -1; - break; - } - if (vendor == NULL) { - if (vendor_in == NULL) { - dbg(udev, "matched global option\n"); - 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). - */ - dbg(udev, "matched vendor/model\n"); - break; - } else { - dbg(udev, "no match\n"); - } - } - - 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) { - err(udev, "can't allocate memory\n"); - retval = -1; - } 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; - - if (optarg) - dbg(udev, "option '%c' arg '%s'\n", option, optarg); - else - dbg(udev, "option '%c'\n", option); - - 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 \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 { - err(udev, "Unknown page code '%s'\n", optarg); - return -1; - } - break; - - case 's': - sg_version = atoi(optarg); - if (sg_version < 3 || sg_version > 4) { - err(udev, "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; - - if (optarg) - dbg(udev, "option '%c' arg '%s'\n", option, optarg); - else - dbg(udev, "option '%c'\n", option); - - 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 { - err(udev, "Unknown page code '%s'\n", optarg); - retval = -1; - } - break; - - default: - err(udev, "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); - dbg(udev, "per dev options: good %d; page code 0x%x\n", 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; - - udev_log_init("scsi_id"); - 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) { - err(udev, "no device specified\n"); - retval = 1; - goto exit; - } - - retval = scsi_id(udev, maj_min_dev); - -exit: - udev_unref(udev); - udev_log_close(); - return retval; -} diff --git a/src/extras/scsi_id/scsi_id.h b/src/extras/scsi_id/scsi_id.h deleted file mode 100644 index 828a98305f..0000000000 --- a/src/extras/scsi_id/scsi_id.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 . - */ - -#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/extras/scsi_id/scsi_serial.c b/src/extras/scsi_id/scsi_serial.c deleted file mode 100644 index f1d63f40cc..0000000000 --- a/src/extras/scsi_id/scsi_serial.c +++ /dev/null @@ -1,990 +0,0 @@ -/* - * Copyright (C) IBM Corp. 2003 - * - * Author: Patrick Mansfield - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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. - */ - - dbg(udev, "got check condition\n"); - - if (sb_len < 1) { - info(udev, "%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) { - info(udev, "%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? - */ - info(udev, "%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 { - info(udev, "%s: invalid sense code 0x%x\n", - dev_scsi->kernel, code); - return -1; - } - info(udev, "%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", - dev_scsi->kernel, sense_key, asc, ascq); - } else { - if (sb_len < 4) { - info(udev, "%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) - info(udev, "%s: old sense key: 0x%x\n", dev_scsi->kernel, sense_buffer[0] & 0x0f); - else - info(udev, "%s: sense = %2x %2x\n", - dev_scsi->kernel, sense_buffer[0], sense_buffer[2]); - info(udev, "%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++) { - dbg(udev, "i %d, j %d\n", i, j); - 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'; - info(udev, "%s: sense dump:\n", dev_scsi->kernel); - info(udev, "%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. - */ - info(udev, "%s: called with no error\n", __FUNCTION__); - return -1; - } - - info(udev, "%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. - */ - info(udev, "%s: called with no error\n", __FUNCTION__); - return -1; - } - - info(udev, "%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) { - info(udev, "buflen %d too long\n", buflen); - return -1; - } - -resend: - dbg(udev, "%s evpd %d, page 0x%x\n", dev_scsi->kernel, evpd, page); - - 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; - } - info(udev, "%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) { - dbg(udev, "%s: Retrying ...\n", dev_scsi->kernel); - goto resend; - } - retval = -1; - } - -error: - if (retval < 0) - info(udev, "%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) { - info(udev, "%s: page 0 not available.\n", dev_scsi->kernel); - return 1; - } - if (buffer[3] > len) { - info(udev, "%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)) { - info(udev, "%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)) { - info(udev, "%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) { - info(udev, "%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) { - dbg(udev, "prepend failed\n"); - 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; - - dbg(udev, "using pre-spc3-83 for %s\n", dev_scsi->kernel); - 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) { - info(udev, "%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); - dbg(udev, "%s id desc %d/%d/%d\n", dev_scsi->kernel, - id_search_list[id_ind].id_type, - id_search_list[id_ind].naa_type, - id_search_list[id_ind].code_set); - if (!retval) { - dbg(udev, " used\n"); - return retval; - } else if (retval < 0) { - dbg(udev, " failed\n"); - return retval; - } else { - dbg(udev, " not used\n"); - } - } - } - 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) { - info(udev, "%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++; - } - dbg(udev, "using pre-spc3-83 for %s\n", dev_scsi->kernel); - 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) { - info(udev, "%s: Invalid page 0x80\n", dev_scsi->kernel); - return 1; - } - - len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; - if (max_len < len) { - info(udev, "%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; - 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; - - dbg(udev, "opening %s\n", devname); - fd = open(devname, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - info(udev, "scsi_id: cannot open %s: %s\n", - devname, strerror(errno)); - return 1; - } - - if (fstat(fd, &statbuf) < 0) { - info(udev, "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); - dbg(udev, "opening %s\n", devname); - 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) { - info(udev, "%s: unsupported page code 0x%d\n", dev_scsi->kernel, page_code); - return 1; - } - - /* - * 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; - } - - dbg(udev, "%s: Checking page0\n", dev_scsi->kernel); - - 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/extras/v4l_id/.gitignore b/src/extras/v4l_id/.gitignore deleted file mode 100644 index dffced9f08..0000000000 --- a/src/extras/v4l_id/.gitignore +++ /dev/null @@ -1 +0,0 @@ -v4l_id diff --git a/src/extras/v4l_id/60-persistent-v4l.rules b/src/extras/v4l_id/60-persistent-v4l.rules deleted file mode 100644 index 93c5ee8c27..0000000000 --- a/src/extras/v4l_id/60-persistent-v4l.rules +++ /dev/null @@ -1,20 +0,0 @@ -# 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/src/extras/v4l_id/v4l_id.c b/src/extras/v4l_id/v4l_id.c deleted file mode 100644 index a2a80b5f43..0000000000 --- a/src/extras/v4l_id/v4l_id.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2009 Kay Sievers - * Copyright (c) 2009 Filippo Argiolas - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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] \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/floppy/.gitignore b/src/floppy/.gitignore new file mode 100644 index 0000000000..939f625a4a --- /dev/null +++ b/src/floppy/.gitignore @@ -0,0 +1 @@ +create_floppy_devices diff --git a/src/floppy/60-floppy.rules b/src/floppy/60-floppy.rules new file mode 100644 index 0000000000..53e4a9e59a --- /dev/null +++ b/src/floppy/60-floppy.rules @@ -0,0 +1,4 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM=="block", KERNEL=="fd[0-9]", ACTION=="add", ATTRS{cmos}=="?*", ENV{CMOS_TYPE}="$attr{cmos}", \ + RUN+="create_floppy_devices -c -t $env{CMOS_TYPE} -m %M -M 0660 -G floppy $root/%k" diff --git a/src/floppy/create_floppy_devices.c b/src/floppy/create_floppy_devices.c new file mode 100644 index 0000000000..f71ef0d809 --- /dev/null +++ b/src/floppy/create_floppy_devices.c @@ -0,0 +1,177 @@ +/* + * Create all possible floppy device based on the CMOS type. + * Based upon code from drivers/block/floppy.c + * + * Copyright(C) 2005, SUSE Linux Products GmbH + * + * Author: Hannes Reinecke + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +static char *table[] = { + "", "d360", "h1200", "u360", "u720", "h360", "h720", + "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410", + "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743", + "h880", "u1040", "u1120", "h1600", "u1760", "u1920", + "u3200", "u3520", "u3840", "u1840", "u800", "u1600", + NULL +}; + +static int t360[] = { 1, 0 }; +static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 }; +static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30, 0 }; +static int *table_sup[] = { NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in }; + +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; + char *dev; + char *devname; + char node[64]; + int type = 0, i, fdnum, c; + int major = 2, minor; + uid_t uid = 0; + gid_t gid = 0; + mode_t mode = 0660; + int create_nodes = 0; + int print_nodes = 0; + int is_err = 0; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + udev_log_init("create_floppy_devices"); + udev_set_log_fn(udev, log_fn); + udev_selinux_init(udev); + + while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) { + switch (c) { + case 'c': + create_nodes = 1; + break; + case 'd': + print_nodes = 1; + break; + case 'U': + uid = util_lookup_user(udev, optarg); + break; + case 'G': + gid = util_lookup_group(udev, optarg); + break; + case 'M': + mode = strtol(optarg, NULL, 0); + mode = mode & 0666; + break; + case 'm': + major = strtol(optarg, NULL, 0); + break; + case 't': + type = strtol(optarg, NULL, 0); + break; + default: + is_err++; + break; + } + } + + if (is_err || optind >= argc) { + printf("Usage: %s [OPTION] device\n" + " -c create\n" + " -d debug\n" + " -m Major number\n" + " -t floppy type number\n" + " -U device node user ownership\n" + " -G device node group owner\n" + " -M device node mode\n" + "\n", argv[0]); + return 1; + } + + dev = argv[optind]; + devname = strrchr(dev, '/'); + if (devname != NULL) + devname = &devname[1]; + else + devname = dev; + if (strncmp(devname, "fd", 2) != 0) { + fprintf(stderr,"Device '%s' is not a floppy device\n", dev); + return 1; + } + + fdnum = strtol(&devname[2], NULL, 10); + if (fdnum < 0 || fdnum > 7) { + fprintf(stderr,"Floppy device number %d out of range (0-7)\n", fdnum); + return 1; + } + if (fdnum > 3) + fdnum += 124; + + if (major < 1) { + fprintf(stderr,"Invalid major number %d\n", major); + return 1; + } + + if (type < 0 || type >= (int) ARRAY_SIZE(table_sup)) { + fprintf(stderr,"Invalid CMOS type %d\n", type); + return 1; + } + + if (type == 0) + return 0; + + i = 0; + while (table_sup[type][i]) { + sprintf(node, "%s%s", dev, table[table_sup[type][i]]); + minor = (table_sup[type][i] << 2) + fdnum; + if (print_nodes) + printf("%s b %.4o %d %d\n", node, mode, major, minor); + if (create_nodes) { + unlink(node); + udev_selinux_setfscreatecon(udev, node, S_IFBLK | mode); + mknod(node, S_IFBLK | mode, makedev(major,minor)); + udev_selinux_resetfscreatecon(udev); + chown(node, uid, gid); + chmod(node, S_IFBLK | mode); + } + i++; + } + + udev_selinux_exit(udev); + udev_unref(udev); + udev_log_close(); +exit: + return 0; +} diff --git a/src/gudev/.gitignore b/src/gudev/.gitignore new file mode 100644 index 0000000000..d20fa523e4 --- /dev/null +++ b/src/gudev/.gitignore @@ -0,0 +1,9 @@ +gtk-doc.make +docs/version.xml +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/COPYING b/src/gudev/COPYING new file mode 100644 index 0000000000..da97db2bd0 --- /dev/null +++ b/src/gudev/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 + + 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. + + + Copyright (C) + + 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/gudev/docs/.gitignore b/src/gudev/docs/.gitignore new file mode 100644 index 0000000000..8eada6d409 --- /dev/null +++ b/src/gudev/docs/.gitignore @@ -0,0 +1,16 @@ +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.stamp +html/* +xml/* +tmpl/* +*.stamp diff --git a/src/gudev/docs/Makefile.am b/src/gudev/docs/Makefile.am new file mode 100644 index 0000000000..2f0a8cb3eb --- /dev/null +++ b/src/gudev/docs/Makefile.am @@ -0,0 +1,106 @@ +## 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 + +# 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=--sgml-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= + +# 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= + +# 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= + +# 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 = \ + $(DBUS_GLIB_CFLAGS) \ + $(GLIB_CFLAGS) \ + -I$(top_srcdir)/src/gudev \ + -I$(top_builddir)/src/gudev + +GTKDOC_LIBS = \ + $(GLIB_LIBS) \ + $(top_builddir)/src/gudev/libgudev-1.0.la + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/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 $(srcsrc) +#TESTS = $(GTKDOC_CHECK) +endif diff --git a/src/gudev/docs/gudev-docs.xml b/src/gudev/docs/gudev-docs.xml new file mode 100644 index 0000000000..f876c3bc05 --- /dev/null +++ b/src/gudev/docs/gudev-docs.xml @@ -0,0 +1,93 @@ + + +]> + + + GUDev Reference Manual + For GUdev version &version; + + + David + Zeuthen + +
+ davidz@redhat.com +
+
+
+ + Bastien + Nocera + +
+ hadess@hadess.net +
+
+
+
+ + + 2011 + The GUDev Authors + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free + Documentation License, Version 1.1 or any later + version published by the Free Software Foundation with no + Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. You may obtain a copy of the GNU Free + Documentation License from the Free Software + Foundation by visiting their Web site or by writing + to: + +
+ The Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, + USA +
+
+ + + Many of the names used by companies to distinguish their + products and services are claimed as trademarks. Where those + names appear in any freedesktop.org documentation, and those + trademarks are made aware to the members of the + freedesktop.org Project, the names have been printed in caps + or initial caps. + +
+
+ + + API Reference + + + This part presents the class and function reference for the + libgudev library. + + + + + + + + + Object Hierarchy + + + + Index + + + Index of new symbols in 165 + + + +
diff --git a/src/gudev/docs/gudev-sections.txt b/src/gudev/docs/gudev-sections.txt new file mode 100644 index 0000000000..213e1a7465 --- /dev/null +++ b/src/gudev/docs/gudev-sections.txt @@ -0,0 +1,113 @@ +
+gudevclient +GUdevClient +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 + +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 + +GUdevClientPrivate +
+ +
+gudevdevice +GUdevDevice +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 + +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 + +GUdevDevicePrivate +
+ +
+gudevenumerator +GUdevEnumerator +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 + +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 + +GUdevEnumeratorPrivate +
+ +
+gudevmarshal + +g_udev_marshal_VOID__STRING_OBJECT +
+ +
+gudevenumtypes + +G_TYPE_UDEV_DEVICE_TYPE +g_udev_device_type_get_type +
diff --git a/src/gudev/docs/gudev.types b/src/gudev/docs/gudev.types new file mode 100644 index 0000000000..a89857a04d --- /dev/null +++ b/src/gudev/docs/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/src/gudev/docs/version.xml.in b/src/gudev/docs/version.xml.in new file mode 100644 index 0000000000..d78bda9342 --- /dev/null +++ b/src/gudev/docs/version.xml.in @@ -0,0 +1 @@ +@VERSION@ 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..a313460817 --- /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 + * + * 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 1 +#include +#include +#include +#include +#include +#include +#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 + * + * 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 +#include + +#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 + * sysfs filesystem) and the udev daemon (through a + * tmpfs 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 + * thread-default main loop + * 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 + * thread-default main loop + * 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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_CLIENT_H__ +#define __G_UDEV_CLIENT_H__ + +#include + +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 + * + * 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 +#include + +#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 /dev) 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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_DEVICE_H__ +#define __G_UDEV_DEVICE_H__ + +#include + +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 + * + * 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 +#include + +#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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_ENUMERATOR_H__ +#define __G_UDEV_ENUMERATOR_H__ + +#include + +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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_ENUMS_H__ +#define __G_UDEV_ENUMS_H__ + +#include + +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 + +/*** 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 + +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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_PRIVATE_H__ +#define __G_UDEV_PRIVATE_H__ + +#include + +#include + +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 + * + * 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 can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_TYPES_H__ +#define __G_UDEV_TYPES_H__ + +#include +#include + +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/keymap/.gitignore b/src/keymap/.gitignore new file mode 100644 index 0000000000..01d62e2b6e --- /dev/null +++ b/src/keymap/.gitignore @@ -0,0 +1,6 @@ +keyboard-force-release.sh +keymap +keys-from-name.gperf +keys-from-name.h +keys-to-name.h +keys.txt diff --git a/src/keymap/95-keyboard-force-release.rules b/src/keymap/95-keyboard-force-release.rules new file mode 100644 index 0000000000..79a1bc1cc4 --- /dev/null +++ b/src/keymap/95-keyboard-force-release.rules @@ -0,0 +1,53 @@ +# 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}=="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*|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" + +ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO Si 1848+u|AMILO Xi 2428", 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}=="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/keymap/95-keymap.rules b/src/keymap/95-keymap.rules new file mode 100644 index 0000000000..26de03dcc7 --- /dev/null +++ b/src/keymap/95-keymap.rules @@ -0,0 +1,169 @@ +# 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}=="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 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" + + +# +# 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[02]* 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}=="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}=="*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" +# 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}=="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/keymap/README.keymap.txt b/src/keymap/README.keymap.txt new file mode 100644 index 0000000000..52d50ed2de --- /dev/null +++ b/src/keymap/README.keymap.txt @@ -0,0 +1,101 @@ += 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 + + fdi2rules.py:: convert hal keymap FDIs into udev rules and key map files + (Please note that this is far from perfect, since the mapping between fdi and + udev rules is not straightforward, and impossible in some cases.) + +== 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 . diff --git a/src/keymap/check-keymaps.sh b/src/keymap/check-keymaps.sh new file mode 100755 index 0000000000..405168c667 --- /dev/null +++ b/src/keymap/check-keymaps.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# check that all key names in keymaps/* are known in +# and that all key maps listed in the rules are valid and present in +# Makefile.am +SRCDIR=${1:-.} +KEYLIST=${2:-src/keymap/keys.txt} +KEYMAPS_DIR=$SRCDIR/src/keymap/keymaps +RULES=$SRCDIR/src/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 src/keymap/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 "src/keymap/keymaps/$m\>" $SRCDIR/Makefile.am || { + echo "ERROR: map file $m is not added to Makefile.am" >&2 + exit 1 + } +done diff --git a/src/keymap/findkeyboards b/src/keymap/findkeyboards new file mode 100755 index 0000000000..9ce27429b2 --- /dev/null +++ b/src/keymap/findkeyboards @@ -0,0 +1,68 @@ +#!/bin/sh -e +# Find "real" keyboard devices and print their device path. +# Author: Martin Pitt +# +# 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/keymap/force-release-maps/common-volume-keys b/src/keymap/force-release-maps/common-volume-keys new file mode 100644 index 0000000000..3a7654d735 --- /dev/null +++ b/src/keymap/force-release-maps/common-volume-keys @@ -0,0 +1,3 @@ +0xa0 #mute +0xae #volume down +0xb0 #volume up diff --git a/src/keymap/force-release-maps/dell-touchpad b/src/keymap/force-release-maps/dell-touchpad new file mode 100644 index 0000000000..18e9bdee66 --- /dev/null +++ b/src/keymap/force-release-maps/dell-touchpad @@ -0,0 +1 @@ +0x9E diff --git a/src/keymap/force-release-maps/hp-other b/src/keymap/force-release-maps/hp-other new file mode 100644 index 0000000000..6621370095 --- /dev/null +++ b/src/keymap/force-release-maps/hp-other @@ -0,0 +1,3 @@ +# list of scancodes (hex or decimal), optional comment +0xd8 # Touchpad off +0xd9 # Touchpad on diff --git a/src/keymap/force-release-maps/samsung-other b/src/keymap/force-release-maps/samsung-other new file mode 100644 index 0000000000..c51123a0b6 --- /dev/null +++ b/src/keymap/force-release-maps/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/src/keymap/keyboard-force-release.sh.in b/src/keymap/keyboard-force-release.sh.in new file mode 100755 index 0000000000..dd040cebc3 --- /dev/null +++ b/src/keymap/keyboard-force-release.sh.in @@ -0,0 +1,22 @@ +#!@rootprefix@/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="@pkglibexecdir@/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/keymap/keymap.c b/src/keymap/keymap.c new file mode 100644 index 0000000000..92ec67b3a6 --- /dev/null +++ b/src/keymap/keymap.c @@ -0,0 +1,447 @@ +/* + * keymap - dump keymap of an evdev device or set a new keymap from a file + * + * Based on keyfuzz by Lennart Poettering + * Adapted for udev-extras by Martin Pitt + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const struct key* lookup_key (const char *str, unsigned int len); + +#include "keys-from-name.h" +#include "keys-to-name.h" + +#define MAX_SCANCODES 1024 + +static int evdev_open(const char *dev) +{ + int fd; + char fn[PATH_MAX]; + + if (strncmp(dev, "/dev", 4) != 0) { + 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, int scancode, int e) +{ + int codes[2]; + + codes[0] = scancode; + if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) { + if (e && errno == EINVAL) { + return -2; + } else { + fprintf(stderr, "EVIOCGKEYCODE: %m\n"); + return -1; + } + } + return codes[1]; +} + +static int evdev_set_keycode(int fd, int scancode, int keycode) +{ + int codes[2]; + + codes[0] = scancode; + codes[1] = 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]; + int scancode, 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; + int scancode, 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; + goto fail; + } + + if (evdev_set_keycode(fd, scancode, new_keycode) < 0) { + r = -1; + goto fail; + } + + if (new_keycode != old_keycode) + fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n", + scancode, new_keycode, old_keycode); + } +fail: + 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(uint32_t 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; + uint32_t 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); +} + +static void help(int error) +{ + const char* h = "Usage: keymap []\n" + " keymap scancode keyname [...]\n" + " keymap -i \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, "r"); + 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]; + snprintf(keymap_path, sizeof(keymap_path), "%s%s", SYSCONFDIR "/udev/keymaps/", filearg); + FILE *f = fopen(keymap_path, "r"); + if (f) { + merge_table(fd, f); + } else { + snprintf(keymap_path, sizeof(keymap_path), "%s%s", PKGLIBEXECDIR "/keymaps/", filearg); + f = fopen(keymap_path, "r"); + 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/keymap/keymaps/acer b/src/keymap/keymaps/acer new file mode 100644 index 0000000000..4e7c297dea --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/acer-aspire_5720 b/src/keymap/keymaps/acer-aspire_5720 new file mode 100644 index 0000000000..1496d63a52 --- /dev/null +++ b/src/keymap/keymaps/acer-aspire_5720 @@ -0,0 +1,4 @@ +0x84 bluetooth # sent when bluetooth module missing, and key pressed +0x92 media # acer arcade +0xD4 bluetooth # bluetooth on +0xD9 bluetooth # bluetooth off diff --git a/src/keymap/keymaps/acer-aspire_5920g b/src/keymap/keymaps/acer-aspire_5920g new file mode 100644 index 0000000000..633c4e854c --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/acer-aspire_6920 b/src/keymap/keymaps/acer-aspire_6920 new file mode 100644 index 0000000000..699c954b4e --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/acer-aspire_8930 b/src/keymap/keymaps/acer-aspire_8930 new file mode 100644 index 0000000000..fb27bfb4f5 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/acer-travelmate_c300 b/src/keymap/keymaps/acer-travelmate_c300 new file mode 100644 index 0000000000..bfef4cf868 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/asus b/src/keymap/keymaps/asus new file mode 100644 index 0000000000..2a5995f982 --- /dev/null +++ b/src/keymap/keymaps/asus @@ -0,0 +1,3 @@ +0xED volumeup +0xEE volumedown +0xEF mute diff --git a/src/keymap/keymaps/compaq-e_evo b/src/keymap/keymaps/compaq-e_evo new file mode 100644 index 0000000000..5fbc573aa4 --- /dev/null +++ b/src/keymap/keymaps/compaq-e_evo @@ -0,0 +1,4 @@ +0xA3 www # I key +0x9A search +0x9E email +0x9F homepage diff --git a/src/keymap/keymaps/dell b/src/keymap/keymaps/dell new file mode 100644 index 0000000000..4f907b3eef --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/dell-latitude-xt2 b/src/keymap/keymaps/dell-latitude-xt2 new file mode 100644 index 0000000000..39872f559d --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/everex-xt5000 b/src/keymap/keymaps/everex-xt5000 new file mode 100644 index 0000000000..4823a832f5 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/fujitsu-amilo_li_2732 b/src/keymap/keymaps/fujitsu-amilo_li_2732 new file mode 100644 index 0000000000..9b8b36a170 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/fujitsu-amilo_pa_2548 b/src/keymap/keymaps/fujitsu-amilo_pa_2548 new file mode 100644 index 0000000000..f7b0c52444 --- /dev/null +++ b/src/keymap/keymaps/fujitsu-amilo_pa_2548 @@ -0,0 +1,3 @@ +0xE0 volumedown +0xE1 volumeup +0xE5 prog1 diff --git a/src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 b/src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 new file mode 100644 index 0000000000..d2e38cbb23 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/fujitsu-amilo_pro_v3205 b/src/keymap/keymaps/fujitsu-amilo_pro_v3205 new file mode 100644 index 0000000000..43e3199d59 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/fujitsu-amilo_si_1520 b/src/keymap/keymaps/fujitsu-amilo_si_1520 new file mode 100644 index 0000000000..1419bd9b5e --- /dev/null +++ b/src/keymap/keymaps/fujitsu-amilo_si_1520 @@ -0,0 +1,6 @@ +0xE1 wlan +0xF3 wlan +0xEE brightnessdown +0xE0 brightnessup +0xE2 bluetooth +0xF7 video diff --git a/src/keymap/keymaps/fujitsu-esprimo_mobile_v5 b/src/keymap/keymaps/fujitsu-esprimo_mobile_v5 new file mode 100644 index 0000000000..d3d056b366 --- /dev/null +++ b/src/keymap/keymaps/fujitsu-esprimo_mobile_v5 @@ -0,0 +1,4 @@ +0xA9 switchvideomode +0xD9 brightnessdown +0xDF sleep +0xEF brightnessup diff --git a/src/keymap/keymaps/fujitsu-esprimo_mobile_v6 b/src/keymap/keymaps/fujitsu-esprimo_mobile_v6 new file mode 100644 index 0000000000..52c70c50cb --- /dev/null +++ b/src/keymap/keymaps/fujitsu-esprimo_mobile_v6 @@ -0,0 +1,2 @@ +0xCE brightnessup +0xEF brightnessdown diff --git a/src/keymap/keymaps/genius-slimstar-320 b/src/keymap/keymaps/genius-slimstar-320 new file mode 100644 index 0000000000..d0a3656dd8 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/hewlett-packard b/src/keymap/keymaps/hewlett-packard new file mode 100644 index 0000000000..4461fa2ce5 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/hewlett-packard-2510p_2530p b/src/keymap/keymaps/hewlett-packard-2510p_2530p new file mode 100644 index 0000000000..41ad2e9b5a --- /dev/null +++ b/src/keymap/keymaps/hewlett-packard-2510p_2530p @@ -0,0 +1,2 @@ +0xD8 f23 # touchpad off +0xD9 f22 # touchpad on diff --git a/src/keymap/keymaps/hewlett-packard-compaq_elitebook b/src/keymap/keymaps/hewlett-packard-compaq_elitebook new file mode 100644 index 0000000000..42007c5483 --- /dev/null +++ b/src/keymap/keymaps/hewlett-packard-compaq_elitebook @@ -0,0 +1,2 @@ +0x88 presentation +0xD9 help # I key (high keycode: "info") diff --git a/src/keymap/keymaps/hewlett-packard-pavilion b/src/keymap/keymaps/hewlett-packard-pavilion new file mode 100644 index 0000000000..3d3cefc8e6 --- /dev/null +++ b/src/keymap/keymaps/hewlett-packard-pavilion @@ -0,0 +1,3 @@ +0x88 media # FIXME: quick play +0xD8 f23 # touchpad off +0xD9 f22 # touchpad on diff --git a/src/keymap/keymaps/hewlett-packard-presario-2100 b/src/keymap/keymaps/hewlett-packard-presario-2100 new file mode 100644 index 0000000000..1df39dcbd2 --- /dev/null +++ b/src/keymap/keymaps/hewlett-packard-presario-2100 @@ -0,0 +1,3 @@ +0xF0 help +0xF1 screenlock +0xF3 search diff --git a/src/keymap/keymaps/hewlett-packard-tablet b/src/keymap/keymaps/hewlett-packard-tablet new file mode 100644 index 0000000000..d19005ab90 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/hewlett-packard-tx2 b/src/keymap/keymaps/hewlett-packard-tx2 new file mode 100644 index 0000000000..36a690fcf6 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint b/src/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint new file mode 100644 index 0000000000..027e50bf88 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/inventec-symphony_6.0_7.0 b/src/keymap/keymaps/inventec-symphony_6.0_7.0 new file mode 100644 index 0000000000..4a8b4ba5a7 --- /dev/null +++ b/src/keymap/keymaps/inventec-symphony_6.0_7.0 @@ -0,0 +1,2 @@ +0xF3 prog2 +0xF4 prog1 diff --git a/src/keymap/keymaps/lenovo-3000 b/src/keymap/keymaps/lenovo-3000 new file mode 100644 index 0000000000..5bd165654a --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/lenovo-ideapad b/src/keymap/keymaps/lenovo-ideapad new file mode 100644 index 0000000000..fc339839f2 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/src/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint new file mode 100644 index 0000000000..47e8846a68 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/lenovo-thinkpad_x200_tablet b/src/keymap/keymaps/lenovo-thinkpad_x200_tablet new file mode 100644 index 0000000000..31ea3b2c70 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/lenovo-thinkpad_x6_tablet b/src/keymap/keymaps/lenovo-thinkpad_x6_tablet new file mode 100644 index 0000000000..6fd16b5662 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/lg-x110 b/src/keymap/keymaps/lg-x110 new file mode 100644 index 0000000000..ba08cba3fe --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/logitech-wave b/src/keymap/keymaps/logitech-wave new file mode 100644 index 0000000000..caa5d5d310 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/logitech-wave-cordless b/src/keymap/keymaps/logitech-wave-cordless new file mode 100644 index 0000000000..a10dad5e4d --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/logitech-wave-pro-cordless b/src/keymap/keymaps/logitech-wave-pro-cordless new file mode 100644 index 0000000000..e7aa02206c --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/maxdata-pro_7000 b/src/keymap/keymaps/maxdata-pro_7000 new file mode 100644 index 0000000000..c0e4f77af4 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/medion-fid2060 b/src/keymap/keymaps/medion-fid2060 new file mode 100644 index 0000000000..5a76c76799 --- /dev/null +++ b/src/keymap/keymaps/medion-fid2060 @@ -0,0 +1,2 @@ +0x6B channeldown # Thottle Down +0x6D channelup # Thottle Up diff --git a/src/keymap/keymaps/medionnb-a555 b/src/keymap/keymaps/medionnb-a555 new file mode 100644 index 0000000000..c3b5dfa60b --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/micro-star b/src/keymap/keymaps/micro-star new file mode 100644 index 0000000000..4a438698ed --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/module-asus-w3j b/src/keymap/keymaps/module-asus-w3j new file mode 100644 index 0000000000..773e0b3e82 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/module-ibm b/src/keymap/keymaps/module-ibm new file mode 100644 index 0000000000..a92dfa2506 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/module-lenovo b/src/keymap/keymaps/module-lenovo new file mode 100644 index 0000000000..8e38883091 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/module-sony b/src/keymap/keymaps/module-sony new file mode 100644 index 0000000000..7c000131d1 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/module-sony-old b/src/keymap/keymaps/module-sony-old new file mode 100644 index 0000000000..596a34258a --- /dev/null +++ b/src/keymap/keymaps/module-sony-old @@ -0,0 +1,2 @@ +0x06 battery +0x07 mute diff --git a/src/keymap/keymaps/module-sony-vgn b/src/keymap/keymaps/module-sony-vgn new file mode 100644 index 0000000000..c8ba001516 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/olpc-xo b/src/keymap/keymaps/olpc-xo new file mode 100644 index 0000000000..34434a121d --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/onkyo b/src/keymap/keymaps/onkyo new file mode 100644 index 0000000000..ee864ade4d --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/oqo-model2 b/src/keymap/keymaps/oqo-model2 new file mode 100644 index 0000000000..b7f4851abe --- /dev/null +++ b/src/keymap/keymaps/oqo-model2 @@ -0,0 +1,5 @@ +0x8E wlan +0xF0 switchvideomode +0xF1 mute +0xF2 volumedown +0xF3 volumeup diff --git a/src/keymap/keymaps/samsung-other b/src/keymap/keymaps/samsung-other new file mode 100644 index 0000000000..3ac0c2f10c --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/samsung-sq1us b/src/keymap/keymaps/samsung-sq1us new file mode 100644 index 0000000000..ea2141ef84 --- /dev/null +++ b/src/keymap/keymaps/samsung-sq1us @@ -0,0 +1,7 @@ +0xD4 menu +0xD8 f1 +0xD9 f10 +0xD6 f3 +0xD7 f9 +0xE4 f5 +0xEE f11 diff --git a/src/keymap/keymaps/samsung-sx20s b/src/keymap/keymaps/samsung-sx20s new file mode 100644 index 0000000000..9d954ee415 --- /dev/null +++ b/src/keymap/keymaps/samsung-sx20s @@ -0,0 +1,4 @@ +0x74 mute +0x75 mute +0x77 f22 # Touchpad on +0x79 f23 # Touchpad off diff --git a/src/keymap/keymaps/toshiba-satellite_a100 b/src/keymap/keymaps/toshiba-satellite_a100 new file mode 100644 index 0000000000..22007be71b --- /dev/null +++ b/src/keymap/keymaps/toshiba-satellite_a100 @@ -0,0 +1,2 @@ +0xA4 stopcd +0xB2 www diff --git a/src/keymap/keymaps/toshiba-satellite_a110 b/src/keymap/keymaps/toshiba-satellite_a110 new file mode 100644 index 0000000000..1429409351 --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/toshiba-satellite_m30x b/src/keymap/keymaps/toshiba-satellite_m30x new file mode 100644 index 0000000000..ae8e34941b --- /dev/null +++ b/src/keymap/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/src/keymap/keymaps/zepto-znote b/src/keymap/keymaps/zepto-znote new file mode 100644 index 0000000000..cf72fda47b --- /dev/null +++ b/src/keymap/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/src/libudev-queue.c b/src/libudev-queue.c index 7a4b563cfa..0e82cb6ae8 100644 --- a/src/libudev-queue.c +++ b/src/libudev-queue.c @@ -322,7 +322,7 @@ UDEV_EXPORT int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue); if (seqnum_udev < seqnum_kernel) { dbg(udev_queue->udev, "queue is empty but kernel events still pending [%llu]<->[%llu]\n", - seqnum_kernel, seqnum_udev); + seqnum_kernel, seqnum_udev); goto out; } diff --git a/src/mtd_probe/.gitignore b/src/mtd_probe/.gitignore new file mode 100644 index 0000000000..82b8ab501f --- /dev/null +++ b/src/mtd_probe/.gitignore @@ -0,0 +1 @@ +mtd_probe diff --git a/src/mtd_probe/75-probe_mtd.rules b/src/mtd_probe/75-probe_mtd.rules new file mode 100644 index 0000000000..c0e0839785 --- /dev/null +++ b/src/mtd_probe/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/src/mtd_probe/mtd_probe.c b/src/mtd_probe/mtd_probe.c new file mode 100644 index 0000000000..1aa08d3851 --- /dev/null +++ b/src/mtd_probe/mtd_probe.c @@ -0,0 +1,51 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + if (argc != 2) { + printf("usage: mtd_probe /dev/mtd[n]\n"); + return 1; + } + + int mtd_fd = open(argv[1], O_RDONLY); + if (mtd_fd == -1) { + perror("open"); + exit(-1); + } + + mtd_info_t mtd_info; + int 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/mtd_probe/mtd_probe.h b/src/mtd_probe/mtd_probe.h new file mode 100644 index 0000000000..2a37ede578 --- /dev/null +++ b/src/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 + +/* 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/mtd_probe/probe_smartmedia.c b/src/mtd_probe/probe_smartmedia.c new file mode 100644 index 0000000000..b3cdefc633 --- /dev/null +++ b/src/mtd_probe/probe_smartmedia.c @@ -0,0 +1,97 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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) +{ + char* cis_buffer = malloc(SM_SECTOR_SIZE); + + if (!cis_buffer) + return; + + if (info->type != MTD_NANDFLASH) + goto exit; + + int sector_size = info->writesize; + int block_size = info->erasesize; + int size_in_megs = info->size / (1024 * 1024); + int spare_count; + + + 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; + } + + + int offset; + int cis_found = 0; + + 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/qemu/42-qemu-usb.rules b/src/qemu/42-qemu-usb.rules new file mode 100644 index 0000000000..a4e3864714 --- /dev/null +++ b/src/qemu/42-qemu-usb.rules @@ -0,0 +1,13 @@ +# +# 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" diff --git a/src/rule_generator/75-cd-aliases-generator.rules b/src/rule_generator/75-cd-aliases-generator.rules new file mode 100644 index 0000000000..e6da0101d6 --- /dev/null +++ b/src/rule_generator/75-cd-aliases-generator.rules @@ -0,0 +1,9 @@ +# these rules generate rules for the /dev/{cdrom,dvd,...} symlinks + +# the "path" of usb/ieee1394 devices changes frequently, use "id" +ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb|ieee1394", ENV{ID_CDROM}=="?*", ENV{GENERATED}!="?*", \ + PROGRAM="write_cd_rules by-id", SYMLINK+="%c", GOTO="persistent_cd_end" + +ACTION=="add", SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", ENV{GENERATED}!="?*", PROGRAM="write_cd_rules", SYMLINK+="%c" + +LABEL="persistent_cd_end" diff --git a/src/rule_generator/75-persistent-net-generator.rules b/src/rule_generator/75-persistent-net-generator.rules new file mode 100644 index 0000000000..4f80573478 --- /dev/null +++ b/src/rule_generator/75-persistent-net-generator.rules @@ -0,0 +1,102 @@ +# do not edit this file, it will be overwritten on update + +# these rules generate rules for persistent network device naming +# +# variables used to communicate: +# MATCHADDR MAC address used for the match +# MATCHID bus_id used for the match +# MATCHDRV driver name used for the match +# MATCHIFTYPE interface type match +# COMMENT comment to add to the generated rule +# INTERFACE_NAME requested name supplied by external tool +# INTERFACE_NEW new interface name returned by rule writer + +ACTION!="add", GOTO="persistent_net_generator_end" +SUBSYSTEM!="net", GOTO="persistent_net_generator_end" + +# ignore the interface if a name has already been set +NAME=="?*", GOTO="persistent_net_generator_end" + +# device name whitelist +KERNEL!="eth*|ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end" + +# ignore Xen virtual interfaces +SUBSYSTEMS=="xen", GOTO="persistent_net_generator_end" + +# read MAC address +ENV{MATCHADDR}="$attr{address}" + +# match interface type +ENV{MATCHIFTYPE}="$attr{type}" + +# ignore KVM virtual interfaces +ENV{MATCHADDR}=="52:54:00:*", GOTO="persistent_net_generator_end" +# ignore VMWare virtual interfaces +ENV{MATCHADDR}=="00:0c:29:*|00:50:56:*", GOTO="persistent_net_generator_end" +# ignore Hyper-V virtual interfaces +ENV{MATCHADDR}=="00:15:5d:*", GOTO="persistent_net_generator_end" + +# These vendors are known to violate the local MAC address assignment scheme +# Interlan, DEC (UNIBUS or QBUS), Apollo, Cisco, Racal-Datacom +ENV{MATCHADDR}=="02:07:01:*", GOTO="globally_administered_whitelist" +# 3Com +ENV{MATCHADDR}=="02:60:60:*", GOTO="globally_administered_whitelist" +# 3Com IBM PC; Imagen; Valid; Cisco; Apple +ENV{MATCHADDR}=="02:60:8c:*", GOTO="globally_administered_whitelist" +# Intel +ENV{MATCHADDR}=="02:a0:c9:*", GOTO="globally_administered_whitelist" +# Olivetti +ENV{MATCHADDR}=="02:aa:3c:*", GOTO="globally_administered_whitelist" +# CMC Masscomp; Silicon Graphics; Prime EXL +ENV{MATCHADDR}=="02:cf:1f:*", GOTO="globally_administered_whitelist" +# Prominet Corporation Gigabit Ethernet Switch +ENV{MATCHADDR}=="02:e0:3b:*", GOTO="globally_administered_whitelist" +# BTI (Bus-Tech, Inc.) IBM Mainframes +ENV{MATCHADDR}=="02:e6:d3:*", GOTO="globally_administered_whitelist" +# Realtek +ENV{MATCHADDR}=="52:54:00:*", GOTO="globally_administered_whitelist" +# Novell 2000 +ENV{MATCHADDR}=="52:54:4c:*", GOTO="globally_administered_whitelist" +# Realtec +ENV{MATCHADDR}=="52:54:ab:*", GOTO="globally_administered_whitelist" +# Kingston Technologies +ENV{MATCHADDR}=="e2:0c:0f:*", GOTO="globally_administered_whitelist" +# Xensource +ENV{MATCHADDR}=="00:16:3e:*", GOTO="globally_administered_whitelist" + +# match interface dev_id +ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}" + +# do not use "locally administered" MAC address +ENV{MATCHADDR}=="?[2367abef]:*", ENV{MATCHADDR}="" + +# do not use empty address +ENV{MATCHADDR}=="00:00:00:00:00:00", ENV{MATCHADDR}="" + +LABEL="globally_administered_whitelist" + +# build comment line for generated rule: +SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device} ($driver)" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="?*", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct} ($driver)" +SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id} ($driver)" +SUBSYSTEMS=="ieee1394", ENV{COMMENT}="Firewire device $attr{host_id})" + +# ibmveth likes to use "locally administered" MAC addresses +DRIVERS=="ibmveth", ENV{MATCHADDR}="$attr{address}", ENV{COMMENT}="ibmveth ($id)" + +# S/390 uses id matches only, do not use MAC address match +SUBSYSTEMS=="ccwgroup", ENV{COMMENT}="S/390 $driver device at $id", ENV{MATCHID}="$id", ENV{MATCHDRV}="$driver", ENV{MATCHADDR}="" + +# see if we got enough data to create a rule +ENV{MATCHADDR}=="", ENV{MATCHID}=="", ENV{INTERFACE_NAME}=="", GOTO="persistent_net_generator_end" + +# default comment +ENV{COMMENT}=="", ENV{COMMENT}="net device ($attr{driver})" + +# write rule +DRIVERS=="?*", IMPORT{program}="write_net_rules" + +# rename interface if needed +ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}" + +LABEL="persistent_net_generator_end" diff --git a/src/rule_generator/rule_generator.functions b/src/rule_generator/rule_generator.functions new file mode 100644 index 0000000000..2eec1b6abf --- /dev/null +++ b/src/rule_generator/rule_generator.functions @@ -0,0 +1,113 @@ +# functions used by the udev rule generator + +# Copyright (C) 2006 Marco d'Itri + +# 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 . + +PATH='/usr/bin:/bin:/usr/sbin:/sbin' + +# Read a single line from file $1 in the $DEVPATH directory. +# The function must not return an error even if the file does not exist. +sysread() { + local file="$1" + [ -e "/sys$DEVPATH/$file" ] || return 0 + local value + read value < "/sys$DEVPATH/$file" || return 0 + echo "$value" +} + +sysreadlink() { + local file="$1" + [ -e "/sys$DEVPATH/$file" ] || return 0 + readlink -f /sys$DEVPATH/$file 2> /dev/null || true +} + +# Return true if a directory is writeable. +writeable() { + if ln -s test-link $1/.is-writeable 2> /dev/null; then + rm -f $1/.is-writeable + return 0 + else + return 1 + fi +} + +# Create a lock file for the current rules file. +lock_rules_file() { + RUNDIR=$(udevadm info --run) + [ -e "$RUNDIR" ] || return 0 + + RULES_LOCK="$RUNDIR/.lock-${RULES_FILE##*/}" + + retry=30 + while ! mkdir $RULES_LOCK 2> /dev/null; do + if [ $retry -eq 0 ]; then + echo "Cannot lock $RULES_FILE!" >&2 + exit 2 + fi + sleep 1 + retry=$(($retry - 1)) + done +} + +unlock_rules_file() { + [ "$RULES_LOCK" ] || return 0 + rmdir $RULES_LOCK || true +} + +# Choose the real rules file if it is writeable or a temporary file if not. +# Both files should be checked later when looking for existing rules. +choose_rules_file() { + RUNDIR=$(udevadm info --run) + local tmp_rules_file="$RUNDIR/tmp-rules--${RULES_FILE##*/}" + [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 + + if writeable ${RULES_FILE%/*}; then + RO_RULES_FILE='/dev/null' + else + RO_RULES_FILE=$RULES_FILE + RULES_FILE=$tmp_rules_file + fi +} + +# Return the name of the first free device. +raw_find_next_available() { + local links="$1" + + local basename=${links%%[ 0-9]*} + local max=-1 + for name in $links; do + local num=${name#$basename} + [ "$num" ] || num=0 + [ $num -gt $max ] && max=$num + done + + local max=$(($max + 1)) + # "name0" actually is just "name" + [ $max -eq 0 ] && return + echo "$max" +} + +# Find all rules matching a key (with action) and a pattern. +find_all_rules() { + local key="$1" + local linkre="$2" + local match="$3" + + local search='.*[[:space:],]'"$key"'"('"$linkre"')".*' + echo $(sed -n -r -e 's/^#.*//' -e "${match}s/${search}/\1/p" \ + $RO_RULES_FILE \ + $([ -e $RULES_FILE ] && echo $RULES_FILE) \ + 2>/dev/null) +} diff --git a/src/rule_generator/write_cd_rules b/src/rule_generator/write_cd_rules new file mode 100644 index 0000000000..645b9cd521 --- /dev/null +++ b/src/rule_generator/write_cd_rules @@ -0,0 +1,126 @@ +#!/bin/sh -e + +# This script is run if an optical drive lacks a rule for persistent naming. +# +# It adds symlinks for optical drives based on the device class determined +# by cdrom_id and used ID_PATH to identify the device. + +# (C) 2006 Marco d'Itri +# +# 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 . + +# debug, if UDEV_LOG= +if [ -n "$UDEV_LOG" ]; then + if [ "$UDEV_LOG" -ge 7 ]; then + set -x + fi +fi + +RULES_FILE="/etc/udev/rules.d/70-persistent-cd.rules" + +. /lib/udev/rule_generator.functions + +find_next_available() { + raw_find_next_available "$(find_all_rules 'SYMLINK\+=' "$1")" +} + +write_rule() { + local match="$1" + local link="$2" + local comment="$3" + + { + if [ "$PRINT_HEADER" ]; then + PRINT_HEADER= + echo "# This file was automatically generated by the $0" + echo "# program, run by the cd-aliases-generator.rules rules file." + echo "#" + echo "# You can modify it, as long as you keep each rule on a single" + echo "# line, and set the \$GENERATED variable." + echo "" + fi + + [ "$comment" ] && echo "# $comment" + echo "$match, SYMLINK+=\"$link\", ENV{GENERATED}=\"1\"" + } >> $RULES_FILE + SYMLINKS="$SYMLINKS $link" +} + +if [ -z "$DEVPATH" ]; then + echo "Missing \$DEVPATH." >&2 + exit 1 +fi +if [ -z "$ID_CDROM" ]; then + echo "$DEVPATH is not a CD reader." >&2 + exit 1 +fi + +if [ "$1" ]; then + METHOD="$1" +else + METHOD='by-path' +fi + +case "$METHOD" in + by-path) + if [ -z "$ID_PATH" ]; then + echo "$DEVPATH not supported by path_id. by-id may work." >&2 + exit 1 + fi + RULE="ENV{ID_PATH}==\"$ID_PATH\"" + ;; + + by-id) + if [ "$ID_SERIAL" ]; then + RULE="ENV{ID_SERIAL}==\"$ID_SERIAL\"" + elif [ "$ID_MODEL" -a "$ID_REVISION" ]; then + RULE="ENV{ID_MODEL}==\"$ID_MODEL\", ENV{ID_REVISION}==\"$ID_REVISION\"" + else + echo "$DEVPATH not supported by ata_id. by-path may work." >&2 + exit 1 + fi + ;; + + *) + echo "Invalid argument (must be either by-path or by-id)." >&2 + exit 1 + ;; +esac + +# Prevent concurrent processes from modifying the file at the same time. +lock_rules_file + +# Check if the rules file is writeable. +choose_rules_file + +link_num=$(find_next_available 'cdrom[0-9]*') + +match="SUBSYSTEM==\"block\", ENV{ID_CDROM}==\"?*\", $RULE" + +comment="$ID_MODEL ($ID_PATH)" + + write_rule "$match" "cdrom$link_num" "$comment" +[ "$ID_CDROM_CD_R" -o "$ID_CDROM_CD_RW" ] && \ + write_rule "$match" "cdrw$link_num" +[ "$ID_CDROM_DVD" ] && \ + write_rule "$match" "dvd$link_num" +[ "$ID_CDROM_DVD_R" -o "$ID_CDROM_DVD_RW" -o "$ID_CDROM_DVD_RAM" ] && \ + write_rule "$match" "dvdrw$link_num" +echo >> $RULES_FILE + +unlock_rules_file + +echo $SYMLINKS + +exit 0 diff --git a/src/rule_generator/write_net_rules b/src/rule_generator/write_net_rules new file mode 100644 index 0000000000..bcea4b09dc --- /dev/null +++ b/src/rule_generator/write_net_rules @@ -0,0 +1,141 @@ +#!/bin/sh -e + +# This script is run to create persistent network device naming rules +# based on properties of the device. +# If the interface needs to be renamed, INTERFACE_NEW= will be printed +# on stdout to allow udev to IMPORT it. + +# variables used to communicate: +# MATCHADDR MAC address used for the match +# MATCHID bus_id used for the match +# MATCHDEVID dev_id used for the match +# MATCHDRV driver name used for the match +# MATCHIFTYPE interface type match +# COMMENT comment to add to the generated rule +# INTERFACE_NAME requested name supplied by external tool +# INTERFACE_NEW new interface name returned by rule writer + +# Copyright (C) 2006 Marco d'Itri +# Copyright (C) 2007 Kay Sievers +# +# 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 . + +# debug, if UDEV_LOG= +if [ -n "$UDEV_LOG" ]; then + if [ "$UDEV_LOG" -ge 7 ]; then + set -x + fi +fi + +RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules' + +. /lib/udev/rule_generator.functions + +interface_name_taken() { + local value="$(find_all_rules 'NAME=' $INTERFACE)" + if [ "$value" ]; then + return 0 + else + return 1 + fi +} + +find_next_available() { + raw_find_next_available "$(find_all_rules 'NAME=' "$1")" +} + +write_rule() { + local match="$1" + local name="$2" + local comment="$3" + + { + if [ "$PRINT_HEADER" ]; then + PRINT_HEADER= + echo "# This file was automatically generated by the $0" + echo "# program, run by the persistent-net-generator.rules rules file." + echo "#" + echo "# You can modify it, as long as you keep each rule on a single" + echo "# line, and change only the value of the NAME= key." + fi + + echo "" + [ "$comment" ] && echo "# $comment" + echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\"" + } >> $RULES_FILE +} + +if [ -z "$INTERFACE" ]; then + echo "missing \$INTERFACE" >&2 + exit 1 +fi + +# Prevent concurrent processes from modifying the file at the same time. +lock_rules_file + +# Check if the rules file is writeable. +choose_rules_file + +# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces +if [ "$MATCHADDR" ]; then + match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\"" +fi + +if [ "$MATCHDRV" ]; then + match="$match, DRIVERS==\"$MATCHDRV\"" +fi + +if [ "$MATCHDEVID" ]; then + match="$match, ATTR{dev_id}==\"$MATCHDEVID\"" +fi + +if [ "$MATCHID" ]; then + match="$match, KERNELS==\"$MATCHID\"" +fi + +if [ "$MATCHIFTYPE" ]; then + match="$match, ATTR{type}==\"$MATCHIFTYPE\"" +fi + +if [ -z "$match" ]; then + echo "missing valid match" >&2 + unlock_rules_file + exit 1 +fi + +basename=${INTERFACE%%[0-9]*} +match="$match, KERNEL==\"$basename*\"" + +if [ "$INTERFACE_NAME" ]; then + # external tools may request a custom name + COMMENT="$COMMENT (custom name provided by external tool)" + if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then + INTERFACE=$INTERFACE_NAME; + echo "INTERFACE_NEW=$INTERFACE" + fi +else + # if a rule using the current name already exists, find a new name + if interface_name_taken; then + INTERFACE="$basename$(find_next_available "$basename[0-9]*")" + # prevent INTERFACE from being "eth" instead of "eth0" + [ "$INTERFACE" = "${INTERFACE%%[ \[\]0-9]*}" ] && INTERFACE=${INTERFACE}0 + echo "INTERFACE_NEW=$INTERFACE" + fi +fi + +write_rule "$match" "$INTERFACE" "$COMMENT" + +unlock_rules_file + +exit 0 diff --git a/src/scsi_id/.gitignore b/src/scsi_id/.gitignore new file mode 100644 index 0000000000..10e9ae743c --- /dev/null +++ b/src/scsi_id/.gitignore @@ -0,0 +1,3 @@ +scsi_id +scsi_id.8 +scsi_id_version.h diff --git a/src/scsi_id/README b/src/scsi_id/README new file mode 100644 index 0000000000..9cfe73991c --- /dev/null +++ b/src/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 or +. diff --git a/src/scsi_id/scsi.h b/src/scsi_id/scsi.h new file mode 100644 index 0000000000..c423cac574 --- /dev/null +++ b/src/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 + +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 ) 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/scsi_id/scsi_id.8 b/src/scsi_id/scsi_id.8 new file mode 100644 index 0000000000..0d4dba9149 --- /dev/null +++ b/src/scsi_id/scsi_id.8 @@ -0,0 +1,119 @@ +.TH SCSI_ID 8 "December 2003" "" "Linux Administrator's Manual" +.SH NAME +scsi_id \- retrieve and generate a unique SCSI identifier +.SH SYNOPSIS +.BI scsi_id +[\fIoptions\fP] +.SH "DESCRIPTION" +.B scsi_id +queries a SCSI device via the SCSI INQUIRY vital product data (VPD) page 0x80 or +0x83 and uses the resulting data to generate a value that is unique across +all SCSI devices that properly support page 0x80 or page 0x83. + +If a result is generated it is sent to standard output, and the program +exits with a zero value. If no identifier is output, the program exits +with a non\-zero value. + +\fBscsi_id\fP is primarily for use by other utilities such as \fBudev\fP +that require a unique SCSI identifier. + +By default all devices are assumed black listed, the \fB\-\-whitelisted\fP option must +be specified on the command line or in the config file for any useful +behaviour. + +SCSI commands are sent directly to the device via the SG_IO ioctl +interface. + +In order to generate unique values for either page 0x80 or page 0x83, the +serial numbers or world wide names are prefixed as follows. + +Identifiers based on page 0x80 are prefixed by the character 'S', the SCSI +vendor, the SCSI product (model) and then the the serial number returned +by page 0x80. For example: + +.sp +.nf +# /usr/lib/udev/scsi_id \-\-page=0x80 \-\-whitelisted \-\-device=/dev/sda +SIBM 3542 1T05078453 +.fi +.P + +Identifiers based on page 0x83 are prefixed by the identifier type +followed by the page 0x83 identifier. For example, a device with a NAA +(Name Address Authority) type of 3 (also in this case the page 0x83 +identifier starts with the NAA value of 6): + +.sp +.nf +# /usr/lib/udev/scsi_id \-\-page=0x83 \-\-whitelisted \-\-device=/dev/sda +3600a0b80000b174b000000d63efc5c8c +.fi +.P + +.SH OPTIONS +.TP +.BI \-\-blacklisted +The default behaviour \- treat the device as black listed, and do nothing +unless a white listed device is found in the scsi_id config\-file. +.TP +.BI \-\-device=\| device\^ +Send SG_IO commands to \fBdevice\fP, such as \fB/dev/sdc\fP. +.TP +.BI \-\-config=\| config\-file +Read configuration and black/white list entries from +.B config\-file +rather than the default +.B /etc/scsi_id.config +file. +.TP +.BI \-\-whitelisted +Treat the device as white listed. The \fB\-\-whitelisted\fP option must be specified +on the command line or in the scsi_id configuration file for +.B scsi_id +to generate any output. +.TP +.BI \-\-page=\| 0x80 | 0x83 | pre-spc3-83 +Use SCSI INQUIRY VPD page code 0x80, 0x83, or pre-spc3-83. +.sp +The default +behaviour is to query the available VPD pages, and use page 0x83 if found, +else page 0x80 if found, else nothing. +.sp +Page pre-spc3-83 should only be utilized for those scsi devices which +are not compliant with the SPC-2 or SPC-3 format for page 83. While this +option is used for older model 4, 5, and 6 EMC Symmetrix devices, its +use with SPC-2 or SPC-3 compliant devices will fallback to the page 83 +format supported by these devices. +.TP +.BI \-\-replace-whitespace +Reformat the output : replace all whitespaces by underscores. +.TP +.BI \-\-export +Export all data in KEY= format used to import in other programs. +.TP +.BI \-\-verbose +Generate verbose debugging output. +.TP +.BI \-\-version +Display version number and exit. +.RE + +.SH "FILES" +.nf +.ft B +.ft +.TP +\fI/etc/scsi_id.config\fP +Configuration of black/white list entries and per device options: +# one config per line, short match strings match longer strings +# vendor=string[,model=string],options= +vendor="ATA",options=-p 0x80 +.RE +.fi +.LP +.SH "SEE ALSO" +.BR udev (7) +.SH AUTHORS +Developed by Patrick Mansfield based on SCSI ID +source included in earlier linux 2.5 kernels, sg_utils source, and SCSI +specifications. diff --git a/src/scsi_id/scsi_id.c b/src/scsi_id/scsi_id.c new file mode 100644 index 0000000000..9bb0d7f538 --- /dev/null +++ b/src/scsi_id/scsi_id.c @@ -0,0 +1,657 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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] = SYSCONFDIR "/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; + 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 char *quote_string = "\"\n"; + static char *comma_string = ",\n"; + char *val; + 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; + + dbg(udev, "vendor='%s'; model='%s'\n", vendor, model); + fd = fopen(config_file, "r"); + if (fd == NULL) { + dbg(udev, "can't open %s\n", config_file); + if (errno == ENOENT) { + return 1; + } else { + err(udev, "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); + err(udev, "can't allocate memory\n"); + return -1; + } + + *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') { + err(udev, "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; + + dbg(udev, "lineno %d: '%s'\n", lineno, buf); + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "VENDOR") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + vendor_in = str1; + + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "MODEL") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + model_in = str1; + str1 = strsep(&buf, "="); + } + } + + if (str1 && strcasecmp(str1, "OPTIONS") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = -1; + break; + } + options_in = str1; + } + dbg(udev, "config file line %d:\n" + " vendor '%s'; model '%s'; options '%s'\n", + lineno, vendor_in, model_in, options_in); + /* + * Only allow: [vendor=foo[,model=bar]]options=stuff + */ + if (!options_in || (!vendor_in && model_in)) { + err(udev, "Error parsing config file line %d '%s'\n", lineno, buffer); + retval = -1; + break; + } + if (vendor == NULL) { + if (vendor_in == NULL) { + dbg(udev, "matched global option\n"); + 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). + */ + dbg(udev, "matched vendor/model\n"); + break; + } else { + dbg(udev, "no match\n"); + } + } + + 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) { + err(udev, "can't allocate memory\n"); + retval = -1; + } 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; + + if (optarg) + dbg(udev, "option '%c' arg '%s'\n", option, optarg); + else + dbg(udev, "option '%c'\n", option); + + 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 \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 { + err(udev, "Unknown page code '%s'\n", optarg); + return -1; + } + break; + + case 's': + sg_version = atoi(optarg); + if (sg_version < 3 || sg_version > 4) { + err(udev, "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; + + if (optarg) + dbg(udev, "option '%c' arg '%s'\n", option, optarg); + else + dbg(udev, "option '%c'\n", option); + + 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 { + err(udev, "Unknown page code '%s'\n", optarg); + retval = -1; + } + break; + + default: + err(udev, "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); + dbg(udev, "per dev options: good %d; page code 0x%x\n", 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; + + udev_log_init("scsi_id"); + 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) { + err(udev, "no device specified\n"); + retval = 1; + goto exit; + } + + retval = scsi_id(udev, maj_min_dev); + +exit: + udev_unref(udev); + udev_log_close(); + return retval; +} diff --git a/src/scsi_id/scsi_id.h b/src/scsi_id/scsi_id.h new file mode 100644 index 0000000000..828a98305f --- /dev/null +++ b/src/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 . + */ + +#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/scsi_id/scsi_serial.c b/src/scsi_id/scsi_serial.c new file mode 100644 index 0000000000..f1d63f40cc --- /dev/null +++ b/src/scsi_id/scsi_serial.c @@ -0,0 +1,990 @@ +/* + * Copyright (C) IBM Corp. 2003 + * + * Author: Patrick Mansfield + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + */ + + dbg(udev, "got check condition\n"); + + if (sb_len < 1) { + info(udev, "%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) { + info(udev, "%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? + */ + info(udev, "%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 { + info(udev, "%s: invalid sense code 0x%x\n", + dev_scsi->kernel, code); + return -1; + } + info(udev, "%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", + dev_scsi->kernel, sense_key, asc, ascq); + } else { + if (sb_len < 4) { + info(udev, "%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) + info(udev, "%s: old sense key: 0x%x\n", dev_scsi->kernel, sense_buffer[0] & 0x0f); + else + info(udev, "%s: sense = %2x %2x\n", + dev_scsi->kernel, sense_buffer[0], sense_buffer[2]); + info(udev, "%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++) { + dbg(udev, "i %d, j %d\n", i, j); + 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'; + info(udev, "%s: sense dump:\n", dev_scsi->kernel); + info(udev, "%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. + */ + info(udev, "%s: called with no error\n", __FUNCTION__); + return -1; + } + + info(udev, "%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. + */ + info(udev, "%s: called with no error\n", __FUNCTION__); + return -1; + } + + info(udev, "%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) { + info(udev, "buflen %d too long\n", buflen); + return -1; + } + +resend: + dbg(udev, "%s evpd %d, page 0x%x\n", dev_scsi->kernel, evpd, page); + + 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; + } + info(udev, "%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) { + dbg(udev, "%s: Retrying ...\n", dev_scsi->kernel); + goto resend; + } + retval = -1; + } + +error: + if (retval < 0) + info(udev, "%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) { + info(udev, "%s: page 0 not available.\n", dev_scsi->kernel); + return 1; + } + if (buffer[3] > len) { + info(udev, "%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)) { + info(udev, "%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)) { + info(udev, "%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) { + info(udev, "%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) { + dbg(udev, "prepend failed\n"); + 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; + + dbg(udev, "using pre-spc3-83 for %s\n", dev_scsi->kernel); + 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) { + info(udev, "%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); + dbg(udev, "%s id desc %d/%d/%d\n", dev_scsi->kernel, + id_search_list[id_ind].id_type, + id_search_list[id_ind].naa_type, + id_search_list[id_ind].code_set); + if (!retval) { + dbg(udev, " used\n"); + return retval; + } else if (retval < 0) { + dbg(udev, " failed\n"); + return retval; + } else { + dbg(udev, " not used\n"); + } + } + } + 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) { + info(udev, "%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++; + } + dbg(udev, "using pre-spc3-83 for %s\n", dev_scsi->kernel); + 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) { + info(udev, "%s: Invalid page 0x80\n", dev_scsi->kernel); + return 1; + } + + len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; + if (max_len < len) { + info(udev, "%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; + 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; + + dbg(udev, "opening %s\n", devname); + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + info(udev, "scsi_id: cannot open %s: %s\n", + devname, strerror(errno)); + return 1; + } + + if (fstat(fd, &statbuf) < 0) { + info(udev, "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); + dbg(udev, "opening %s\n", devname); + 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) { + info(udev, "%s: unsupported page code 0x%d\n", dev_scsi->kernel, page_code); + return 1; + } + + /* + * 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; + } + + dbg(udev, "%s: Checking page0\n", dev_scsi->kernel); + + 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/v4l_id/.gitignore b/src/v4l_id/.gitignore new file mode 100644 index 0000000000..dffced9f08 --- /dev/null +++ b/src/v4l_id/.gitignore @@ -0,0 +1 @@ +v4l_id diff --git a/src/v4l_id/60-persistent-v4l.rules b/src/v4l_id/60-persistent-v4l.rules new file mode 100644 index 0000000000..93c5ee8c27 --- /dev/null +++ b/src/v4l_id/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/src/v4l_id/v4l_id.c b/src/v4l_id/v4l_id.c new file mode 100644 index 0000000000..a2a80b5f43 --- /dev/null +++ b/src/v4l_id/v4l_id.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2009 Kay Sievers + * Copyright (c) 2009 Filippo Argiolas + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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] \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; +} -- cgit v1.2.3-54-g00ecf