#!/usr/bin/perl

# Copyright 2021 by Andrey Cherepanov (cas@altlinux.org)

# This program is free software; you can redistribute it and/or modify it
# under the terms of GNU General Public License (GPL) version 3 or later.

# Script for export USB devices by usbip

use strict;
use warnings;

my $config = "/etc/xrdp-usb";
my $usbip_host_bound= "/sys/bus/usb/drivers/usbip-host/match_busid";
my @allowed;
my $list_bound;
my $usbid;
my $busid;

# Read all allowed ids from config file to array
sub read_allowed {
    @allowed = ();
    open( my $file, "<", $config ) or return 1;
    while( my $l = <$file> ) {
        if( $l =~ /^\s*([0-9a-fA-F]+:[0-9a-fA-F*]+)/ ) {
	    #print "$1\n";
            push( @allowed, $1 );
        }
    }
    close( $file );
    return 1;
}

# Check and export each allowed device
sub is_allowed {
    my $dev = shift;
    my $vendor;
    my $device;
    my $v;
    my $d;

    ( $vendor, $device ) = split( ":", $dev );

    foreach (@allowed) {
        ( $v, $d ) = split( ":", $_ );
        # Compare allowed pattern and vendor:device
        if( ( $vendor eq $v ) and ( ( $d eq '*' ) or ( $device eq $d ) ) ) {
            return 1;
        }
    }

    return 0;
}

read_allowed();

# Check already bound
open( my $bound, "<", $usbip_host_bound );
$list_bound = <$bound>;
close( $bound );

# Process available devices
open( DEVICES, "sudo -n /usr/sbin/usbip list -pl 2>/dev/null|" );
while ( <DEVICES> ) {
    ( undef, $busid, undef, $usbid ) = split /[=#]/;
    if( is_allowed( $usbid ) ) {
        # Export device
        print "EXPORT USB $usbid ($busid)\n";

        # Check if in bound list
        if( $list_bound =~ /\b$busid\b/ ) {
            system( "sudo", "-n", "/usr/sbin/usbip", "unbind", "-b", "$busid" );
        }

        system( "sudo", "-n", "/usr/sbin/usbip", "bind", "-b", "$busid" );
    }
}
close( DEVICES );
