#!/usr/bin/perl
# 
# Read specified files from AKAI S3000 disk.
# Copyright (c) 1997, Hiroyuki Ohsaki.
# All rights reserved.
# 
# $Id: akairead,v 1.2 1998/06/30 01:35:27 oosaki Exp ohsaki $
# 

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

use Synth::AkaiDisk qw(qualify_path unqualify_path join_path);
use Getopt::Std;
use File::Basename;
use integer;
use strict;

my %EXTS = (100 => 'adr',
	    115 => 'a1s',
	    113 => 'aql',
	    112 => 'a1p',
	    120 => 'afx',
	    237 => 'aml',
	    240 => 'a3p',
	    243 => 'a3s');

sub read_file {
    my($dir, $disk, $path, %entry) = @_;

    my $name = unqualify_path(basename($path));
    $name = join_path($dir, $name);
    $name .= ".$EXTS{$entry{type}}" if (exists $EXTS{$entry{type}});

    print STDERR "reading $path\n  -> $name\n" if $::opt_v;
    system qq(mkdir -p $dir) unless (-d $dir);
    $disk->read_file($path, $name) || die "read: $path: $!\n";
}

sub usage {
    my $prog = basename($0);
    die <<EOF;
usage: $prog [-vR] [-f file] [-p partition] [-d dir] path...
 -v       verbose mode
 -R       read all files recursively
 -f file  specify Akai disk image (default \$AKAI_DISK)
 -p part  read from part-th partition (default 1)
 -d dir   all output goes to dir
EOF
}

getopts('vRf:p:d:') || usage;
@ARGV || usage;

my $dir = $::opt_d || '.';
my $file = $::opt_f || $ENV{AKAI_DISK} || '/dev/mo';
my $part = $::opt_p || 1;

my $disk = new Synth::AkaiDisk($file, $part) || die "new: $file: $!\n";

while (@ARGV) {
    # read file properties
    my $path = shift;
    $path = qualify_path($path);
    (my(%entry) = $disk->stat($path)) || die "stat: $path: $!\n";

    # if $path is a directory, get all files in it
    if ($entry{type} == 1 or $entry{type} == 3) {
	my(%entries) = $disk->readdir($path);
	my $key;
	for $key (sort { $entries{$a}->{at} <=> $entries{$b}->{at} }
		  keys %entries) {

	    my %entry = %{$entries{$key}};

	    # traverse all subdirectories if -R is set
	    if ($::opt_R) {
		if ($entry{type} == 1 or $entry{type} == 3) {
		    push(@ARGV, join_path($path, $key));
		}
	    }
		
	    # don't read directory itself
	    next if ($entry{type} == 1 or $entry{type} == 3);

	    read_file(join_path($dir, unqualify_path($path)), 
		      $disk, join_path($path, $key), %entry);
	}
    } else {
	read_file($dir, $disk, $path, %entry);
    }
}

__END__

=head1 NAME

akairead - Read files from Akai S1000/S3000 HDD/CD-ROM

=head1 SYNOPSIS

  akairead [-vR] [-f file] [-p partition] [-d dir] path...

=head1 DESCRIPTION

This manual page documents B<akairead>.  This program extracts files
from HDD/CD-ROM in Akai S1000/S3000 format.  By default, B<akairead>
copies I<path> in Akai HDD/CD-ROM to the current directory.  If
I<path> is a directory (or volume in Akai terminology), B<akairead>
creates a directory named I<path> in the current directory, and then
copies all files under I<path> to the created directory.

The notation of the pathname, I<path>, in B<akairead> is almost
equivalent to that of conventional UNIX systems.  See L<akailist(1)>
for more detail.

=head1 OPTIONS

=over 4

=item C<-v>

Verbose mode.  Print much information for debugging.

=item C<-R>

Retrieve all files under I<path> recursively.

=item C<-f> file

Specify the regular file of Akai disk image or the block device file
of Akai HDD/CD-ROM.  Usually, this should be the block device of HDD
or CD-ROM such as F</dev/sda>.  If this option is omitted, the
environment variable I<AKAI_DISK> is used as the default device.  If
I<AKAI_DISK> is not defined, F</dev/mo> is assumed.

=item C<-p> partition

Specify the partition number for which B<akairead> works.  The first
partition is 1.  By default, the first partition is used.

=item C<-d> directory

All output files goes to I<directory> instead of the current directory.

=back

=head1 EXAMPLES

This section shows several example usage of B<akairead>.

=over 4

=item - Copy F</ACOUSTIC PNO/GRAND PIANO> to the current directory.

  akairead /acoustic_pno/grand_piano    

=item - Copy all files in the directory F</ACOUSTIC PNO>.

  akairead /acoustic_pno

=item - Backup all files in the second partition to F</work>.

  akairead -R -p2 -d /work /

=back

=head1 SEE ALSO

akaitools(1), akaiformat(1), akailist(1), akaimkdir(1), akairead(1),
akaiwrite(1), epslist(1), epsread(1), eps2akai(1), wav2akai(1),
any2akai(1), akaiconv(1) 

=head1 AUTHOR

Hiroyuki Ohsaki <ohsaki@lsnl.jp>

=cut

