|
| 1 | +#!/usr/bin/env perl |
| 2 | +# VFS-wrapper for MS-DOS IMG files using mtools |
| 3 | +# |
| 4 | +# Written by twojstaryzdomu ([email protected]), 2011 |
| 5 | +# |
| 6 | + |
| 7 | +my ( $cmd, $archive, @args ) = @ARGV; |
| 8 | +my $drive = 'b'; |
| 9 | +my $actions = { |
| 10 | + list => "mdir -f -i", |
| 11 | + copyout => "mcopy -m -n -o -p -i", |
| 12 | + copyin => "mcopy -m -n -o -p -i", |
| 13 | + rm => "mdel -i", |
| 14 | + mkdir => "mmd -i", |
| 15 | + rmdir => "mrd -i", |
| 16 | + test => "logger" |
| 17 | +}; |
| 18 | + |
| 19 | +my $regex_list = qr"^(\S+)\s+(\S*)\s+(\S+)\s+(\d{4})-(\d{2})-(\d{2})\s+(\d{1,2}):(\d{1,2})(?:\s*)(\S+)*\s*$"; |
| 20 | + |
| 21 | +sub print_debug { |
| 22 | + print "@_\n" if exists $ENV{DEBUG}; |
| 23 | +} |
| 24 | + |
| 25 | +sub run_cmd { |
| 26 | + my $cmd = shift; |
| 27 | + my @output = ( do { open( my $line, "$cmd | " ) or die "$0: Can't run $cmd"; <$line>; } ); |
| 28 | + print_debug "run_cmd $cmd"; |
| 29 | + return \@output; |
| 30 | +} |
| 31 | + |
| 32 | +sub default_handler { |
| 33 | + my ( $cmd, $archive, @args ) = ( @_ ); |
| 34 | + if ( $cmd eq 'copyin' ) { |
| 35 | + if ( my ( $name, $ext ) = $args[0] =~ /(\w+)\.(\w+)$/ ) { |
| 36 | + die "filename $name.$ext too long to copy to $archive\n" if ( length( $name ) > 8 || length( $ext ) > 3 ); |
| 37 | + } |
| 38 | + $args[0] = "::$args[0]"; |
| 39 | + @args = reverse @args; |
| 40 | + } |
| 41 | + elsif ( $cmd eq 'copyout' ) { |
| 42 | + $args[0] = "::$args[0]"; |
| 43 | + } |
| 44 | + my $output = run_cmd "$actions->{ $cmd } \'$archive\' @args"; |
| 45 | + if ( $cmd eq 'list' ) { |
| 46 | + foreach ( @{ $output } ) { |
| 47 | + chomp; |
| 48 | + next if /^$/; |
| 49 | + if ( my ( $name, $ext, $size, $year, $mon, $day, $hours, $mins, $longname ) = $_ =~ /$regex_list/ ) { |
| 50 | + print_debug "list: name = $name, ext = $ext, size = $size, year = $year, mon = $mon, day = $day, hours = $hours, mins = $mins, longname = $longname"; |
| 51 | + next if ( $name eq '.' || $name eq '..' ); |
| 52 | + my $perms = $size ne '<DIR>' |
| 53 | + ? '-rw-r--r--' |
| 54 | + : 'drwxr-xr-x'; |
| 55 | + my $path = $longname ? "$args[0]/" . $longname |
| 56 | + : uc( "$args[0]/" . $name ) |
| 57 | + . ( $ext ? ".$ext" |
| 58 | + : "" ); |
| 59 | + $secs = defined $secs ? $secs : "00"; |
| 60 | + printf "%-10s 1 %-8d %-8d %8s %s/%s/%s %s:%s:%s %s", $perms, $<, |
| 61 | + $(, $size ne '<DIR>' ? $size : 0, $mon, $day, $year, $hours, $mins, $secs, $path |
| 62 | + . "\n"; |
| 63 | + default_handler( $cmd, $archive, $path ) if ( $size eq '<DIR>' ); |
| 64 | + } |
| 65 | + else { |
| 66 | + print_debug "list: skipped: $_"; |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +sub run { |
| 73 | + my ( $archive, @args ) = ( @_ ); |
| 74 | + my $size_kb = ( -s $archive ) / 1024; |
| 75 | + my $cmd = "dosbox -noautoexec -c \'IMGMOUNT -size $size_kb $drive: \'$archive\'\' -c '$drive:\' -c"; |
| 76 | + my $output = run_cmd "$cmd @args"; |
| 77 | +} |
| 78 | + |
| 79 | +sub check_mtools { |
| 80 | + my $cmd = shift; |
| 81 | + my ( $tool ) = $actions->{ $cmd } =~ /^(\w+)/; |
| 82 | + foreach ( split( ":", $ENV{PATH} ) ) { |
| 83 | + $found = 1 if -e "$_/$tool" |
| 84 | + } |
| 85 | + die "Cannot find command $cmd, are mtools installed?\n" unless $found; |
| 86 | +} |
| 87 | + |
| 88 | +print_debug "$0: cmd = $cmd; archive = $archive; args = @args"; |
| 89 | +check_mtools( $cmd ); |
| 90 | +die "$archive does not exist\n" unless -f "$archive"; |
| 91 | +exists $actions->{ $cmd } ? default_handler( $cmd, $archive, @args ) |
| 92 | + : die "mode $cmd not available\n"; |
0 commit comments