#!/usr/bin/perl

#Einstellungen:
#Pfad zum mp3-cgi im WWW
$mypath="/cgi-bin/mp3/";

#Lokaler Pfad zu den mp3s
$mp3path="/server/mp3/";

#ffentlicher Pfad zu den mp3s
$publicmp3="http://stargate.gernoth.loc/pub/mp3/";
#$publicmp3="/mpoint/stargate/server/mp3/";

#Name dieses Skripts (sollte passen)
$myname=$mypath."mp3";

#Mime-Typ der Playlist (audio/x-mpegurl)
$mimetyp="audio/x-mpegurl";

#Zeichentabelle:
$urlchars[0][0]='%'; $urlchars[0][1]='%25';
$urlchars[1][0]=' '; $urlchars[1][1]='%20';
$urlchars[2][0]='\?'; $urlchars[2][1]='%3F';
$urlchars[3][0]='!'; $urlchars[3][1]='%21';
$urlchars[4][0]='\$'; $urlchars[4][1]='%24';
$urlchars[5][0]='\#'; $urlchars[5][1]='%23';
$urlchars[6][0]='\+'; $urlchars[6][1]='%2B';
$urlchars[7][0]='"'; $urlchars[7][1]='%22';
$urlchars[8][0]=''; $urlchars[8][1]='%A7';
$urlchars[9][0]='\('; $urlchars[9][1]='%28';
$urlchars[10][0]='\)'; $urlchars[10][1]='%29';
$urlchars[11][0]='='; $urlchars[11][1]='%3D';
$urlchars[12][0]=''; $urlchars[12][1]='%B2';
$urlchars[13][0]=''; $urlchars[13][1]='%B3';
$urlchars[14][0]='\['; $urlchars[14][1]='%5B';
$urlchars[15][0]='\]'; $urlchars[15][1]='%5D';
$urlchars[16][0]='{'; $urlchars[16][1]='%7B';
$urlchars[17][0]='}'; $urlchars[17][1]='%7D';
$urlchars[18][0]='\\\\'; $urlchars[18][1]='%5C';
$urlchars[19][0]='~'; $urlchars[19][1]='%7E';
$urlchars[20][0]="'"; $urlchars[20][1]='%27';
$urlchars[21][0]='<'; $urlchars[21][1]='%3C';
$urlchars[22][0]='>'; $urlchars[22][1]='%3E';
$urlchars[23][0]='\|'; $urlchars[23][1]='%7C';
$urlchars[24][0]=';'; $urlchars[24][1]='%3B';
$urlchars[25][0]=':'; $urlchars[25][1]='%3A';
$urlchars[26][0]='&'; $urlchars[26][1]='%26';
$urlchars[27][0]=','; $urlchars[27][1]='%2C';
$urlchars[28][0]=''; $urlchars[28][1]='%FC';
$urlchars[29][0]=''; $urlchars[29][1]='%F6';
$urlchars[30][0]=''; $urlchars[30][1]='%E4';
$urlchars[31][0]=''; $urlchars[31][1]='%DC';
$urlchars[32][0]=''; $urlchars[32][1]='%D6';
$urlchars[33][0]=''; $urlchars[33][1]='%D4';
$urlchars[34][0]=''; $urlchars[34][1]='%DF';
$urlchars[35][0]=''; $urlchars[35][1]='%B0';
$urlchars[36][0]='\^'; $urlchars[36][1]='%5E';
$urlchars[37][0]=''; $urlchars[37][1]='%AC';
$urlchars[38][0]=' '; $urlchars[38][1]='\+';
$urlchars[39][0]='';

sub urlencode(@)
{
  my($x) = @_;
  $n=0;
  while ( $urlchars[$n][0] ne '' )
  {
    $x =~ s/$urlchars[$n][0]/$urlchars[$n][1]/g;
    $n++;
  }  
  $x;
}

sub urldecode(@)
{
  my($x) = @_;
  $n=0;
  while ( $urlchars[$n][0] ne '' )
  {
    $nospecial=$urlchars[$n][0];
    $nospecial=~ s/\\//g;
    $x =~ s/$urlchars[$n][1]/$nospecial/g;
    $n++;
  }
  $x =~ s/%2F/\//g;
  $x
}

sub relocate(@)
{
  my($url)=@_;
  print "Content-type: text/html\n";
  $host=$ENV{"HTTP_HOST"};
  $saddr="http://".$host;
  $location=$saddr.urlencode($url);
  print "Location: ".$location."\n\n";
  print "<HTML><HEAD><TITLE>Moved</TITLE></HEAD><BODY>Document moved <A HREF=\"".$location."\">here</A>.</BODY></HTML>\n";
  exit 0;
}

$zeile=$ENV{"PATH_INFO"};

($nix,$aktion,$dpinfo)=split(/\//,$zeile,3);

if ( $aktion eq "" )
{
  relocate($myname."/list/");
}

if ( $aktion eq "play" )
{
  relocate($myname."/playlist/".$dpinfo.".m3u");
}

if ( $aktion eq "playlist" )
{
  print "Content-type: ".$mimetyp."\n\n";
  $file=$dpinfo;
  $file=~ s/.m3u$//g;
  if ( substr($publicmp3,0,7) = "http://" )
  {
    $file=urlencode($file);
  }
  print $publicmp3.$file."\n";
  exit 0;
}

if ($aktion eq "genlist" )
{

  sub fileout(@)
  {
    my($filename)=@_;

    if ( substr($publicmp3,0,7) eq "http://" )
    {
      $filename=urlencode($filename);
    }
    print $publicmp3.$filename."\n";
  }

  #Rekursives absteigen in den Verzeichnisbaum:
  sub recursedir(@)
  {
    my ($dirname)=@_;
    my(@dirarray);
    my($arraycount);
    my($actdatei);
    my($laufv);


    $arraycount=0;
    opendir(DIRH, $mp3path.$dirname);
    $dirinfo="a";
    while ($dirinfo ne "")
    {
      $dirinfo=readdir(DIRH);
      if ( substr($dirinfo,0,1) ne "." && $dirinfo ne "" )
      {
        $dirarray[$arraycount]=$dirinfo;
        $arraycount++;
      }
    }
    closedir(DIRH);    
    for ($laufv=0;$laufv<=$arraycount-1;$laufv++)
    {
      $actdatei=$dirname."/".$dirarray[$laufv];
      ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($mp3path.$actdatei);
      if ( substr($mode,0,1) eq "1" )
      {
        #Juhu, ein Unterverzeichnis! Rekursion!
        recursedir($actdatei);
      } else {
        $ismp3=($actdatei=~ m/\.mp3$/gi);
        if ( $ismp3 ne '' )
        {
          fileout($actdatei);
        }
      }
    }
  }


  #Zusammengestricktes POST-Parsen:
  $laenge = $ENV{'CONTENT_LENGTH'};
  read(STDIN,$myvars,$laenge);
  @inhalt=split(/\&/,$myvars);
  $i=1;

  print "Content-type: ".$mimetyp."\n\n";
#  print "Content-type: text/plain\n\n";
  ($muell,$stammdir)=split(/=/,urldecode($inhalt[0]),2);
  while ( $inhalt[$i] ne '' )
  {
    ($datei[$i-1])=split(/=/,urldecode($inhalt[$i]));
    $i++;
  }
  $i--;$i--;
  for ($j=0;$j<=$i;$j++)
  {
    $file=$stammdir.$datei[$j];
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($mp3path.$file);
    if ( substr($mode,0,1) ne '1' )
    {
      fileout($file);
    } else {
      recursedir($file);
    }
  }
  exit 0;
}

if ( $aktion eq "list" )
{
  if ( substr($dpinfo,length($dpinfo)-1,1) ne "/" && $dpinfo ne "")
  {
    relocate($myname.$zeile."/");
  }
  print "Content-type: text/html\n\n";
  print "<HTML>\n";
  print "<HEAD><TITLE>Verzeichnis /".$dpinfo."</TITLE></HEAD>\n";
  print "<BODY>\n";
  print "<CENTER><H2>MP3-Verzeichnis /".$dpinfo."</H2></CENTER>\n";
  print '<FORM ACTION="'.$myname."/genlist/".'" METHOD="POST">'."\n";
  print '<INPUT TYPE="hidden" NAME="my_mp3directory" VALUE="'.urlencode($dpinfo).'">';
  $dirnum=-1;
  $filenum=-1;
  $dir="";
  $dateien="";
  opendir(DH, $mp3path.$dpinfo);
    $dirinfo="a";
    while( $dirinfo ne "")
    {
      $dirinfo=readdir(DH);
      if ( substr($dirinfo,0,1) ne "." && $dirinfo ne "")
      {
        $realfile=$mp3path.$dpinfo.$dirinfo;
        ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($realfile);
        if ( substr($mode,0,1) eq "1" )
        {
          #Verzeichnis
          $dirnum++;
          $dir[$dirnum]=$dirinfo;
        } else {
          #Datei
          $ismp3=($dirinfo=~ m/\.mp3$/gi);
          if ( $ismp3 ne "" )
          {
            $filenum++;
            $datei[$filenum]=$dirinfo;
          }
        }        
      }
    }
  closedir(DH);
  $buttons='<CENTER><INPUT TYPE="submit" VALUE="Playliste abspielen">&nbsp;<INPUT TYPE="reset" VALUE="Eingaben l&ouml;schen"></CENTER>';
  print $buttons;
  print "<H3>Verzeichnisse:</H3>\n";
  if ( $dpinfo ne "" )
  {
    print '<IMG SRC="'.$mypath."icons/back.gif".'" ALT="[DIR]" WIDTH="20" HEIGHT="22"> <A HREF="../"><B>&Uuml;bergeordnetes Verzeichnis</B></A><BR>'."\n";
  }
  
  @dirs=sort @dir;
  for ( $i=0; $i<=$dirnum; $i++ )
  {
    print '<IMG SRC="'.$mypath."icons/folder.gif".'" ALT="[DIR]" WIDTH="20" HEIGHT="22">';
    print ' <INPUT TYPE="checkbox" NAME="'.$dirs[$i].'"> ';
    print '<A HREF="'.urlencode("".$myname."/list/".$dpinfo.$dirs[$i]."/").'">'.$dirs[$i].'</A><BR>'."\n";  
  }
  if ( $filenum ne "-1" )
  {
    print $buttons;
    print "<H3>Dateien:</H3>\n";
    @dateien=sort @datei;
    for ( $i=0; $i<=$filenum; $i++ )
    {
      print '<IMG SRC="'.$mypath."icons/sound1.gif".'" ALT="[MP3]" WIDTH="20" HEIGHT="22">';
      print ' <INPUT TYPE="checkbox" NAME="'.$dateien[$i].'"> ';
      print '<A HREF="'.urlencode("".$myname."/play/".$dpinfo.$dateien[$i]).'">'.$dateien[$i]."</A><BR>\n";
    }
  }
  print $buttons;
  print "</FORM><BR><BR><HR>\n";
  print "<FONT SIZE=\"-1\">&copy; Michael Gernoth</FONT>";
  print "</BODY></HTML>\n";
  exit 0;
}

print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>404</TITLE><BODY><H1>404 Aktion unbekannt: $aktion</H1></BOD></HTML>\n";
