#!/usr/bin/perl
# 
# List the contents of Ensoniq EPS disk.
# Copyright (c) 1997, Hiroyuki Ohsaki.
# All rights reserved.
# 
# $Id: epslist,v 1.1 1997/03/21 19:19:23 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::EpsDisk qw(qualify_path unqualify_path join_path);
use Getopt::Std;
use File::Basename;
use integer;
use strict;

my %ID = (0 => 'Unused',
	  1 => 'EPS OS',
	  2 => 'Sub Directory',
	  3 => 'EPS Instrument',
	  4 => 'EPS Bank',
	  5 => 'EPS Seq',
	  6 => 'EPS Song',
	  7 => 'EPS SysEx',
	  8 => '..',
	  9 => 'EPS Macro',
	  23 => 'EPS-16 Bank',
	  24 => 'EPS-16 Effect',
	  25 => 'EPS-16 Seq',
	  26 => 'EPS-16 Song',
	  27 => 'EPS-16 OS',
	  29 => 'ASR-10 Song',
	  30 => 'ASR-10 Bank',
	  33 => 'ASR-10 Effect',
	  34 => 'ASR-10 Macro');

sub show_entry {
    my($disk, $path, %entry) = @_;
    
    if ($::opt_u) {
	$path = unqualify_path($path);
    } else {
	$path = basename($path);
    }

    if ($::opt_l) {
	printf "%-14s %9d %9d %s\n",
	($ID{$entry{type}} || 'UNKNOWN'), $entry{start}, $entry{size}, $path;
    } else {
	print "$path\n";
    }
}

sub usage {
    my $prog = basename($0);
    die <<EOF;
usage: $prog [-luR] [-f file] [path...]
 -l       list in long format
 -u       list file names in UNIX format
 -R       traverse all subdirectories recursively
 -f file  specify EPS disk image (default \$EPS_DISK)
EOF
}

getopts('luRf:') || usage;

my $file = $::opt_f || $ENV{EPS_DISK} || '/dev/cdrom';

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

@ARGV || push(@ARGV, '/');
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, list all files in it
    if ($entry{type} == 2) {	
	my(%entries) =  $disk->readdir($path);
	print "$path:\n" if (!$::opt_u);
	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} == 2) {
		    push(@ARGV, join_path($path, $key));
		}
	    }

	    # skip pointer to the parent directory
	    next if ($entry{type} == 8); 

	    show_entry($disk, join_path($path, $key), %entry);
	}
	print "\n" if (!$::opt_u and (@ARGV > 0));
    } else {
	show_entry($disk, $path, %entry);
    }
}

__END__

=head1 NAME

epslist - List the contents of Ensoniq EPS HDD/CD-ROM

=head1 SYNOPSIS

  akailist [-luR] [-f file] [path...]

=head1 DESCRIPTION

This manual page documents B<epslist>.  This program lists the
contents of HDD/CD-ROM in Ensoniq EPS format as like the I<ls(1)>
command in UNIX systems.  B<epslist> is almost identical to
B<akailist> except that it works for Ensoniq EPS disks rather than
Akai S1000/S3000 disks.  See L<akailist(1)> for more information.

B<epslist> can recognize GKH format files as well as EDA format files.

=head1 OPTIONS

=over 4

=item C<-l>

In addition to the file name, file type, file location (in blocks),
and file size (in bytes) are also displayed.

=item C<-u>

All uppercase characters are changed to lowercase, and all spaces are
replaced by underscore.  This options is designed to use with standard
UNIX commands. See L<akailist(1)/EXAMPLES>.

=item C<-R>

All directories including subdirectories are listed recursively.  

=item C<-f> file

Specify the regular file of EPS disk image or the block device file of
EPS 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<EPS_DISK> is used as the default device.  If
I<EPS_DISK> is not defined, F</dev/cdrom> is assumed.

=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 <oosaki@ics.es.osaka-u.ac.jp>

=cut

