#!/usr/bin/perl

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

use vars qw /
%CONFIG
%form
%cookie
$max_dir_size
@dl_questions
@question
/;

my @dl_questions=();

my @question=(
    'Purpose for your download',
    'Just browsing',
    'I need it for the project of mine',
    'Want to take part in the development',
    'I need information for my own proprietary project'
);
push(@dl_questions,\@question);

my @question=(
    'Question 2',
    'Answer 2.1',
    'Answer 2.2',
    'Answer 2.3',
    'Answer 2.4'
);
push(@dl_questions,\@question);



sub Result {
    my ($result,$write_cookie,$rstr,$rwith)=@_;

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

    if ($write_cookie>0) {
        my $cookie1=cookie(
            -name=>'cvsget',
            -value=>'skip_dl-info',
            -expires=>'+5y',
        );
        print header(
            -cookie=>[$cookie1],
            -type=>'text/html',
            -charset=>''
        );
    } else {
        print header(
            -type=>'text/html',
            -charset=>''
        );
    }
    if ($rstr ne '' && $rwith ne '') {
        my $html=$template->output;
        $html=~s/$rstr/$rwith/;
        print $html;
    } else {
        print $template->output;
    }
    exit;
}

sub JSDownload {
    my $dl_param='do_download=now';
    if (index($ENV{REQUEST_URI},'?')>0) {
        $dl_param='&'.$dl_param;
    } else {
        $dl_param='?'.$dl_param;
    }
    my $filename='';
    my $body=<<EOF

    <b>Contacting our website, please wait for a window to appear.</b><br>
    If download fails to begin automatically in 30 seconds, <a href="$ENV{REQUEST_URI}$dl_param">click here to download module from CVS</a>.
    Note: preparing download file of some very large CVS module can take more than a minute, please be patient.
    <p>
    If you still can't get the file, please contact webmaster.

    <p>

    $filename

    <SCRIPT LANGUAGE=Javascript>
    <!--
    function JSDownload() {
    window.location = "$ENV{REQUEST_URI}$dl_param";
    }
    -->
    </SCRIPT>

EOF
;

    if ($cookie{cvsget} eq 'skip_dl-info') {
        Result($body,0,"<BODY","<BODY onLoad=\"JSDownload();\" ");
    } else {
        Result($body,1,"<BODY","<BODY onLoad=\"JSDownload();\" ");
    }
}

sub Display_Form {
    my $body='';
    $body=<<EOF
    To help us improve... bla bla bla.. please fill the following form..
    <p>
    <form method=post action="$ENV{REQUEST_URI}">
    <table border=0 width=450>
    <tr><td colspan=2><b>First name</b></td><td><input type=text name=firstname value='' size=40 maxlength=50></td></tr>
    <tr><td colspan=2><b>Last name</b></td><td><input type=text name=lastname value='' size=40 maxlength=50></td></tr>
    <tr><td colspan=2>Position</td><td><input type=text name=position value='' size=40 maxlength=50></td></tr>
    <tr><td colspan=2><b>Organization</b></td><td>&nbsp;</td></tr>
    <tr><td width=20>&nbsp;</td><td><b>Name</b></td><td><input type=text name=orgname value='' size=40 maxlength=50></td></tr>
    <tr><td width=20>&nbsp;</td><td>Phone</td><td><input type=text name=phone value='' size=40 maxlength=50></td></tr>
    <tr><td width=20>&nbsp;</td><td>WWW</td><td><input type=text name=www value='' size=40 maxlength=50></td></tr>
    <tr><td width=20>&nbsp;</td><td>Email</td><td><input type=text name=email value='' size=40 maxlength=50></td></tr>
    <tr><td width=20>&nbsp;</td><td valign=top>Address</td><td><textarea name=address rows=4 cols=40></textarea></td></tr>
    <tr><td colspan=2>Country</td><td><input type=text name=country value='' size=40 maxlength=50></td></tr>
    <tr><td colspan=2 valign=top>Remarks</td><td><textarea name=remarks rows=4 cols=40></textarea></td></tr>
    <tr><td colspan=3>&nbsp;<br>
EOF
;

    my $q1=0;
    foreach my $question (@dl_questions) {
        $q1++;
        my @question=@{$question};
        my $q2=0;
        $body.='<p>';
        foreach my $elt (@question) {
            $q2++;
            if ($q2==2) {
                $body.='<ul>';
            }
            if ($q2>1) {
                $body.="<input type=checkbox name='cb-$q1$q2'>&nbsp; &nbsp;";
            }
            $body.="$elt<br>";
        }
        $body.='</ul>';

    }

    $body.=<<EOF
    </ul>
    <center>
    <hr>
    <input type=submit value='Download'>
    <input type=hidden name=do_download value='save_form'>
    </td></tr>

    </table>
    </form>
EOF
;
    Result($body);
}


sub Save_Form {

    my $address=$form{address};
    $address=~s!\r\n!; !sg;

    my $remarks=$form{remarks};
    $remarks=~s!\r\n! !sg;

    my $message='';

    my $do_log=0;
    if ($form{firstname} ne '' || $form{lastname} ne '' || $form{position} ne '' 
      || $form{orgname} ne '' || $form{www} ne '' || $form{email} ne '' || $address ne '' 
      || $form{country} ne '' || $remarks ne '') {
        $do_log=1;
    }
    foreach my $key (keys %form) {
       $do_log=1 if ($key=~m/cb/ && $form{$key} eq 'on');
    }

    my $org_log=0;
    if ($form{orgname} ne '' || $form{phone} ne '' || $form{www} ne '' || $form{email} ne '' || $address ne '') {
        $org_log=1;
    }

    if ($do_log && open(LOG,">>$CONFIG{download_info_log_file}")) {
        $message.="\n----- $ENV{REMOTE_ADDR} ".OC::Time_To_Str(time)." ----\n";
        $message.="First name: $form{firstname}\n" if ($form{firstname} ne '');
        $message.="Last name: $form{lastname}\n" if ($form{lastname} ne '');
        $message.="Position: $form{position}\n" if ($form{position} ne '');
        if ($org_log) {
            $message.="Organization\n";
            $message.="    Name: $form{orgname}\n" if ($form{orgname} ne '');
            $message.="    Phone: $form{phone}\n" if ($form{phone} ne '');
            $message.="    WWW: $form{www}\n" if ($form{www} ne '');
            $message.="    Email: $form{email}\n" if ($form{email} ne '');
            $message.="    Address: $address\n" if ($address ne '');
        }
        $message.="Country: $form{country}\n" if ($form{country} ne '');
        $message.="Remarks: $remarks\n" if ($remarks ne '');

        my $q1=0;
        foreach my $question (@dl_questions) {
            $q1++;
            my @question=@{$question};
            my $q2=0;
            my $q='';
            foreach my $elt (@question) {
                $q2++;
                if ($q2==1) {
                    $q="$elt\n";
                } else {
                    if ($form{"cb-$q1$q2"} eq 'on') {
                        $message.="$q * $elt\n";
                        $q='';
                    }
                }
                
            }
        }
        print LOG $message;
        close(LOG);
    }
}

sub Check_Size {
    my ($file)=@_;
    my $du=`nice -n 19 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. You will have to
            use CVS client program to get files from cvs. See <a href='/cvs.shtml'>cvs.shtml</a>.");
        } else {

        }
    }
}

sub Redirect {
    my $file=OC::Finalize_Path($_[0]);
    OC::Log("redirecting to existing file: $file");
    my $url=OC::Url($file);
    print redirect(-uri=>$url);
    exit;
}

sub Cat_File {
    my ($path,$file,$filename)=@_;
    if ($filename eq '') {
        $filename=$file;
        $filename=~s!^.*/([^/]+)$!$1!;
    }
    if (scalar(keys %cookie)<1) {
        OC::Log("no cookies - $ENV{REQUEST_URI} - requested file: $path/$file");
        Result("We are using cookies to prevent robot downloading, 
          that means you must have cookies enabled in your browser. Now click
          this link to get the file: <a href='$ENV{REQUEST_URI}'>$file</a>",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 (OC::File_Type("$path/$file")==$OC::_FILE) {
        Redirect("$path/$file");
    } else {
        Result("Cannot open file: $path/$file");
        OC::Error_Log("Cannot open file: $path/$file");
    }
}

sub Prepare_Filename {
    my ($filename,$tag)=@_;
    if ($tag ne '') {
        my $ftag=substr($tag,3);
        $filename.="-$ftag";
    }
    $filename=~s!/$!!;
    $filename=~s![/\.]!_!g;
    $filename=~s!^.*/([^/]+)$!$1!;
    $filename.=".tar.gz";
    return $filename;
}

sub Tar_Folder {
    my ($path,$file,$tag)=@_;
    my $filename=Prepare_Filename($file,$tag);
    `cd $path; nice -n 19 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{max_download_size}=300*1024*1024; # 300 MB
    %form=();
    my $query=new CGI;
    foreach ($query->param) {
	$form{$_}=$query->param($_);
    }
    %cookie=();
    foreach ($query->cookie) {
        $cookie{$_}=$query->cookie($_);
    }

    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}");
    }

    if ($form{do_download} eq '' && $cookie{'cvsget'} ne 'skip_dl-info') {
        Display_Form;
    } 
    if ($form{do_download} eq 'save_form') {
        Save_Form;
    }
    if ($form{do_download} ne 'now') {
        JSDownload;
    }

    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: "."$CONFIG{www_folder}/$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{cvsget_cache_folder}/";
        `mkdir -p $folder`;
        my $type=OC::File_Type("$CONFIG{cvsroot}/".$path);
	if ($type==$OC::_FILE) {
            $path=~s!,v$!!;
            if (OC::File_Type("$folder/".Prepare_Filename($path,$tag))==$OC::_FILE) {
                Redirect("$folder/".Prepare_Filename($path,$tag));
            }
            Check_Size("$CONFIG{cvsroot}/$path");
            OC::Log("Checkout ,v file: $path");
            `cd $folder; nice -n 19 cvs -d $CONFIG{cvsroot} -Q checkout $tag "$path"`;
            Cat_File($folder,$path);
        } elsif ($type==$OC::_FOLDER) {
            Check_Size("$CONFIG{cvsroot}/$path");
            if (OC::File_Type("$folder/".Prepare_Filename($path,$tag))==$OC::_FILE) {
                Redirect("$folder/".Prepare_Filename($path,$tag));
            }
            OC::Log("Checkout and tar folder: $path");
            `cd $folder; nice -n 19 cvs -d $CONFIG{cvsroot} -Q checkout $tag "$path"`;
            Tar_Folder($folder,$path,$tag);
	} 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;
                    if ($tag ne '') {
                        my $ftag=substr($tag,3);
                        $filename.="-$ftag";
                    }
                    $filename=~s![/\.]!_!g;
                    $filename.=".tar.gz";
                    if (OC::File_Type("$folder/".Prepare_Filename($path,$tag))==$OC::_FILE) {
                        Redirect("$folder/".Prepare_Filename($path,$tag));
                    }
                    OC::Log("Checkout and tar file: $path > $filename");
                    `cd $folder; nice -n 19 cvs -d $CONFIG{cvsroot} -Q checkout $tag "$path"; nice -n 19 tar czf "$filename" *`;
                    Cat_File($folder,$filename);
                } else {
                    if (OC::File_Type("$folder/$path")==$OC::_FILE) {
                        Redirect("$folder/$path");
                    }
                    OC::Log("Checkout file: $path");
                    `cd $folder; nice -n 19 cvs -d $CONFIG{cvsroot} -Q checkout $tag "$path"`;
                    Cat_File($folder,$path);
                }
            } else {
                Result("Requested item not found");
            }            
        }

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


Main;