#!/usr/bin/perl use strict; $|=1; my $DEV="/sys/bus/usb/devices"; sub getline{ my($path)=@_; open(my $f,"<",$DEV."/".$path) || do { # print "failed opening $path: $!\n"; return ""; }; my $l=<$f>; close($f); chomp($l); return $l; }; my %found; my %done; sub gosub { my ($dev,$grep)=@_; my $dh; my $dir; opendir($dh, $DEV."/".$dev) || do { # print "Failure for $dev?\n"; return ""; }; ($dir)=grep {/$grep/} grep {/^[^.]/} readdir($dh); if($dir eq ""){ return ""; }; close $dh; $dev.="/".$dir; return $dev; }; sub getdev{ my ($dev)=@_; my $dh; my $dir; $dev=gosub($dev,":1") || return ""; $dev=gosub($dev,"^host"); $dev=gosub($dev,"^target") || return ""; $dev=~/target(.*)/; $dev=gosub($dev,$1) || return ""; $dev=gosub($dev,"^block") || return ""; $dev=gosub($dev,".") || return ""; $dev=~m!/([^/]*)$!; my $r=$1; if($r!~/^sd/){ print "Strange device? $dev -> $r\n"; return ""; }; return $r; }; my %pids; use POSIX ":sys_wait_h"; my $kid; $SIG{CHLD}=sub { do { $kid = waitpid(-1, WNOHANG); delete $pids{$kid}; }while $kid>0; }; sub dwim{ my($dev)=@_; # print ("checking $dev\n"); my $pr=getline($dev."/idProduct"); return -1 if($pr eq ""); my $ve=getline($dev."/idVendor"); my $mf=getline($dev."/manufacturer"); # print "$pr:$ve\n"; if("$ve:$pr" eq "16c0:08ac") { return 1 if $done{$dev}==1; my $sdev=getdev($dev); if ($sdev eq ""){ print "$dev not ready.\n"; return 1; }; print "Mass storage $dev -> $sdev\n"; my $pid = fork(); if (not defined $pid) { die "fork failed\n"; } elsif ($pid == 0) { system("./mass $sdev $dev"); exit(0); } else { $pids{$pid}=1; } $done{$dev}=1; return 1; }; if("$ve:$pr" eq "04cc:0003") { return 1 if $done{$dev}==2; my $sdev=getdev($dev); if ($sdev eq ""){ print "$dev not ready.\n"; return 1; }; print "flash $dev -> $sdev\n"; system("./flash $sdev $dev"); $done{$dev}=2; return 1; }; print "$ve:$pr [$mf] @ "; return -1; }; my %disable; while(1){ opendir(my $dh, $DEV); my @paths=grep {/^[^.]/} readdir($dh); close $dh; # print "f: ",join(",",@files),"\n"; device: for my $path (@paths){ next if ($disable{$path}); next if $path =~ /^usb/; next if $path =~ /:/; # print "p $path\n"; $found{$path}=1; my $res=dwim($path); if($res==-1){ print "$path -- ignoring it forever\n"; $disable{$path}=1; }; }; for my $a (keys %done){ if (!$found{$a}){ delete $done{$a}; print "$a vanished\n"; }; }; %found=(); # print "\n"; sleep(1); print scalar(keys %pids),"\r"; };