1#!/usr/bin/perl -w 2# Eject using mode change 3# $Rev: 114 $ $Date: 2009-10-19 14:01:11 +0100 (Mon, 19 Oct 2009) $ 4 5use Fcntl; 6use Config; 7use Sys::Syslog; 8 9$dev = shift @ARGV; 10$method = shift @ARGV; 11 12# 13# Use the old eject method if specified 14# 15 16if (! $method) 17{ 18 # Use classic eject method 19 -x "/usr/sbin/eject" and exec "/usr/sbin/eject $dev"; 20 -x "/usr/bin/eject" and exec "/usr/bin/eject $dev"; 21 -x "/bin/eject" and exec "/bin/eject $dev"; 22 system "eject $dev"; 23 exit 0; 24} 25 26openlog( $0, "nofatal", "local0" ); 27 28# 29# Some time sensitive condition exists on some versions of some distributions. 30# Have a few attempts at finding the device before sending the IOCTL command. 31# Sleep for a second after each failed attempt and give up after 5. 32# 33 34$found_dev = 0; 35for ($i=0 ; $i<5 ; $i++ ) 36{ 37 if (sysopen(USB, $dev, O_RDWR)) 38 { 39 $found_dev = 1; 40 next; 41 } 42 else 43 { 44 sleep 1; 45 } 46} 47 48if (! $found_dev) 49{ 50 syslog( "error", "Unable to find given device: $dev\n" ); 51 syslog( "error", "$!" ); 52} 53else 54{ 55 syslog( "info", "Found device $dev\n" ); 56 57 #struct usbdevfs_ctrltransfer { 58 # __u8 bRequestType; 59 # __u8 bRequest; 60 # __u16 wValue; 61 # __u16 wIndex; 62 # __u16 wLength; 63 # __u32 timeout; /* in milliseconds */ 64 # void *data; 65 #}; 66 67 # ctrl_transfer.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; 68 # ctrl_transfer.bRequest = 1; 69 # ctrl_transfer.wValue = 0; 70 # ctrl_transfer.wIndex = 2; 71 72 $buffer = pack("CCSSSLxxxxxxxx", (0x02 << 5), 0x0a, 0, 0, 0, 0); 73 74 #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) 75 $ioctl = ($Config{longsize} == 8) ? 0xc0185500 : 0xc0105500; 76 77 ioctl(USB, $ioctl, $buffer) or syslog( "warning", "USB ioctl error $!\n" ); 78 close USB 79} 80 81closelog(); 82