#!/usr/bin/perl

use strict;
use MIME::Types qw(by_suffix by_mediatype);
use CGI qw/:standard/;
use CGI::Carp qw(fatalsToBrowser);
use Digest::MD5 qw(md5_hex);
use HTML::Template;
push(@INC,'/home/oc/cgi-bin/');
use lib '/home/oc/cgi-bin/';
use OC;

use vars qw /
%CONFIG
%form
$max_dir_size
/;

sub Result {
    my ($result)=@_;

    my $template=HTML::Template->new(
       	filename=>$CONFIG{tmpl_cvsget_file},
    );
    $template->param(
        no_panel=>1,
        title=>"Download",
        body=>$result,
    );

    print header(
        -type=>'text/html',
        -charset=>''
    );
    print $template->output;
    exit;
}

sub Check_Size {
    my ($file)=@_;
    my $du=`du $file`;
    $du=~s!.*\n(.*)\n$!$1!s;
    $du=~s!^(\d+)[^\d]+.*$!$1!s;
    unless ($du=~m/^\d+$/) {
        Result("Requested item not found: $file");
    } else {
        unless (($du*1024)<$CONFIG{max_download_size}) {
            Result("Directory size too big ($du KB) to create tar.gz file.");
        } else {

        }
    }
}

sub Cat_File {
    my ($path,$file,$filename)=@_;
    if ($filename eq '') {
        $filename=$file;
        $filename=~s!^.*/([^/]+)$!$1!;
    }
    my ($mime_type, $encoding) = by_suffix($file);
    $mime_type="text/plain" if ($mime_type eq '');
    print "Content-type: $mime_type\nContent-Disposition: inline; filename=$filename\n\n";
    if (open(FILE,"$path/$file")) {
        my $buffer='';
        while (read(FILE, $buffer, 16*1024)) {
            print $buffer;
        }
        close(FILE);
        my $time=OC::Time_To_Str(time);
        my $ip=$ENV{REMOTE_ADDR};
        `echo $time\t$ip\t$path/$file >> /tmp/cvsget`;
    } else {
        Result("Cannot open file: $path/$file");
    }
}


sub Tar_Folder {
    my ($path,$file)=@_;
    my $filename=$file;
    $filename=~s!/$!!;
    $filename=~s!/!_!g;
    $filename=~s!^.*/([^/]+)$!$1!;
    $filename.=".tar.gz";
    `cd $path; tar czf $filename $file`;
    Cat_File($path,$filename);
}

sub Main {
    $ENV{'PATH'}='/usr/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin:.';
    %CONFIG=%OC::CONFIG;
    $CONFIG{cvs_tmp_folder}="/home/oc/www/tmp/download";
    $CONFIG{max_download_size}=100*1024*1024; # 100 MB
    %form=();
    my $query=new CGI;
    foreach ($query->param) {
	$form{$_}=$query->param($_);
    }

    my $path='';
    my $found=0;
    my $tag="";
    my $tar=0;


    if ($form{module} ne '' && index($form{module},"..")<0 && index($form{module},"CVSROOT")<0) {
        $ENV{PATH_INFO}="/$form{module}";
        $tar=1;
    }
    if ($form{tag}=~m!^[\.A-Z0-9_-]+$!i) {
        $tag="-r $form{tag}";
    } elsif ($form{tag} ne '') {
        Result("Invalid tag: $form{tag}");
    }
    if ($form{revision}=~m!^[\.A-Z0-9_-]+$!i) {
        $tag="-r $form{revision}";
    } elsif ($form{revision} ne '') {
        Result("Invalid revision: $form{revision}");
    }

    unless ($ENV{HTTP_REFERER}=~m/opencores/i) {
        my $tag_rev="";
        if ($form{tag} ne '') {
            $tag_rev.="$form{tag}";
        }
        if ($form{revision} ne '') {
            if ($tag_rev ne '') {
                $tag_rev.="&";
            }
            $tag_rev.="$form{revision}";
        }
        if ($tag_rev ne '') {
            $tag_rev="?".$tag_rev;
        }
        my $url="$CONFIG{cvsget_url}/$ENV{PATH_INFO}$tag_rev";
        $url=~s!//!/!g;
        Result("Please click here: <a href='$url'>$url</a>");
    }

    if ($ENV{PATH_INFO}=~m!^/projects/[A-Za-z0-9_-]+!) {
        $path=$ENV{PATH_INFO};
        $path=~s!^/!!;
        $path=~s!^projects/!cores/!;

        my $type=OC::File_Type("$CONFIG{www_folder}/$path");
        if ($type==$OC::_FILE) {
            Cat_File($CONFIG{www_folder},$path);
#        } elsif ($type==$OC::_FOLDER) {
#            Check_Size("$CONFIG{www_folder}/$path");
#            Tar_Folder($CONFIG{www_folder},$path);
        } else {
            Result("Requested item not found: ".$path);
        }
        
    } elsif ($ENV{PATH_INFO}=~m!^/[A-Za-z0-9]+! && !($ENV{PATH_INFO}=~m/\.\./)) {
        $path=$ENV{PATH_INFO};
        $path=~s!^/cvs/!!;
        $path=~s!^/!!;
        
        my $count=0;
        my $folder="$CONFIG{cvs_tmp_folder}/".md5_hex(time+$count);
        while (defined OC::File_Type($folder)) {
            $count++;
            $folder="$CONFIG{cvs_tmp_folder}/".md5_hex(time+$count);
        }
        `mkdir -p $folder`;
        my $type=OC::File_Type("$CONFIG{cvsroot}/".$path);
	if ($type==$OC::_FILE) {
            Check_Size("$CONFIG{cvsroot}/$path");
            $path=~s!,v$!!;
            `cd $folder; cvs -d $CONFIG{cvsroot} -Q checkout $tag $path`;
            Cat_File($folder,$path);
        } elsif ($type==$OC::_FOLDER) {
            Check_Size("$CONFIG{cvsroot}/$path");
            `cd $folder; cvs -d $CONFIG{cvsroot} -Q checkout $tag $path`;
            Tar_Folder($folder,$path);
	} else {
            $type=OC::File_Type("$CONFIG{cvsroot}/$path,v");
            if ($type==$OC::_FILE) {
                Check_Size("$CONFIG{cvsroot}/$path,v");
                if ($tar>0) {
                    my $filename=$path;
                    $filename=~s![/\.]!_!g;
                    $filename.=".tar.gz";
                    `cd $folder; cvs -d $CONFIG{cvsroot} -Q checkout $tag $path; tar czf $filename *`;
                    Cat_File($folder,$filename);
                } else {
                    `cd $folder; cvs -d $CONFIG{cvsroot} -Q checkout $tag $path`;
                    Cat_File($folder,$path);
                }
            } else {
                Result("Requested item not found");
            }            
        }
        if ($folder=~m!^$CONFIG{cvs_tmp_folder}!) {
            `rm -rf $folder`;
        }

    } else {
        Result("Unknown object");
    }
    
}



Main;
