#!/usr/bin/perl -w =pod =head1 NAME watchusb - Monitor dbus(1) for a particular device =head1 DESCRIPTION A quick and dirty hack to watch the dbus system for insert/removal events for a specific device and execute a program on either. As for dbus itself, WHO THE FUCK DOCUMENTS THIS STUFF? Oh, right, I'm trying to land a job somewhere, I should probably be professional. =head1 PROFESSIONAL DESCRIPTION ...No, I just can't do it. Holy shit, that documentation was f'n painful. =head1 BACK TO THE OTHER DESCRIPTION Anyway, every time there's a DBus event, this program checks the list of devices to see if the target was present and is now absent, or vice versa. In the former case, it calls the program named in $device_chg with 'start' as its sole argument; in the opposite case, it calls $device_chg with 'stop'. Useful for activating screensavers, forgetting ssh passphrases, whatever. If you manage to install a USB port in your front door that uses this program to turn a servo motor one way or another to lock or unlock your deadbolt, I'd I like to hear about it. Please email me with pictures of the project. One of those things that gives me wood that I'd really like to do, but'll never be able to. =head1 LICENSE Public domain. Please credit the author when you think it's appropriate. =head1 AUTHOR Johnny Cuervo =head1 VERSION $Revision: 1.1 $ =cut use Sys::Syslog qw(:DEFAULT setlogsock); open STDIN, "<", "/dev/null"; open STDOUT, ">", "/dev/null"; open STDERR, ">", "/dev/null"; setpgrp; exit 0 if (fork); exit 0 if (fork); setlogsock 'unix'; openlog $0, 'pid', 'daemon'; $SIG{'__WARN__'} = sub { syslog 'info', '%s', $_[0]; }; warn "Running\n"; $device = 'usb_device_90c_1000_AA04012700011144'; $plugged_in = 0; # Status of the device, last we heard $device_chg = "/home/jack/bin/usb-storage-hook"; sub basename ($) { my @path = split /\//, $_[0]; return $path[$#path]; } sub check_usb_drive ($) { my $mgr = shift; my $found = 0; foreach my $dev (@{$mgr->GetAllDevices}) { if (basename($dev) eq $device) { $found = 1; last; } } if ($plugged_in && ! $found) { # # Drive removed # warn "Device removed\n"; system $device_chg, "stop"; } elsif ($found && ! $plugged_in) { warn "Device inserted\n"; system $device_chg, "start"; } $plugged_in = $found; # # Fallthrough, no change # return; } use Net::DBus; use Net::DBus::Reactor; my $bus = Net::DBus->system || die $!; my $hal = $bus->get_service('org.freedesktop.Hal') || die; my $mgr = $hal->get_object('/org/freedesktop/Hal/Manager', 'org.freedesktop.Hal.Manager') || die; my $re = Net::DBus::Reactor->new; $re->add_hook(Net::DBus::Callback->new( 'method' => sub { check_usb_drive $mgr; }, ) ); $re->add_timeout(100, Net::DBus::Callback->new('method' => sub { })); $re->run;