#! /usr/bin/perl
#
# $Header: //sapdb/TOOLSRC/develop/sys/src/BuildPackage/Tools.pm#1 $
# $DateTime: 2002/02/19 16:40:04 $
# $Change: 16574 $
#
# Desc: helper functions for BuildPackage

package BuildPackage::Tools;

use File::Copy;
use Cwd;
use Exporter;

@ISA =('Exporter');
@EXPORT = ('getMD5Sum','add_file','insert_file','remove_file',
			'do_cmd','makedir','find','deltree');


sub setErrMsgHandler{
	my ($handler) = @_;
	*err = $handler;
}

sub setMsgHandler{
	my ($handler) = @_;
	*msg = $handler;
}



sub getMD5Sum{
	my ($file) = @_;
	-f $file || err("cannot get md5sum of $file: $!\n") && return undef;
	my $md5sum = `md5sum $file 2>&1`;
      my $output = $md5sum;
	$md5sum =~ s/\s+\S+//;
      $md5sum =~ /^[a-f|0-9]{32}$/ || err ("cannot get md5sum of $file: $output\n") && return undef;
	return $md5sum;
}



sub add_file{
        my ($file,$target_dir,$target,$list) = @_;
        -f $file or return undef;
        -d $target_dest || return undef;
        $target =~/^\// and return undef;
        $file =~ s/\\/\//g;
        $target_dir =~ s/\\/\//g;
        $target_dir =~ s/\/$//g;
        $file =~ s/\\/\//g;
        my ($dir) = ($target =~ /^(.*)\/\w+$/);
        if ($dir =~ /\S/){
                makedir($target_dir.'/'.$dir) || return undef;
        }
        copy($file,$target_dir.'/'.$target) || return undef;
         my $md5sum = `md5sum $file`;
        $md5sum =~ s/\s+\S+//;
        $md5sum =~ /^[a-f|0-9]{32}$/ || return undef;
        my $list_file = $target_dir.'/'.$list;
        my @list_buf;
        open (LST,$list_file) || return undef;
        while(<LST>){
                chomp;
                /\S/ or next;
                /^"$target"/ and next;
                push @list_buf,$_;
        }
        close(LST);
        push @list_buf,"\"$target\" $md5sum";
        open (LST,'>'.$list_file) || return undef;
        foreach (sort @list_buf){
                print LST "$_\n";
        }
        close(LST);
        return 1;
}

sub insert_file {
        my ($buildroot,$file,$list)=@_;
        -d $buildroot || return undef;
        -f "$buildroot/$file" || return undef;
        -f "$buildroot/$list" || return undef;
        my @list_buf;
        open (LST,"$buildroot/$list") || return undef;
        while(<LST>){
                chomp;
                /\S/ or next;
                /^"$file"/ and next;
                push @list_buf,$_;
        }
        close(LST);
        my $md5sum = `md5sum $buildroot/$file`;
        $md5sum =~ s/\s+\S+//;
        $md5sum =~ /^[a-f|0-9]{32}$/ || return undef;
        push @list_buf,"\"$file\" $md5sum";
        open (LST,">$buildroot/$list") || return undef;
        foreach (sort @list_buf){
                print LST "$_\n";
        }
        close(LST);
        return 1;
}

sub remove_file{
        my ($buildroot,$file,$list) = @_;
        $buildroot =~ s/\\/\//g;
        $buildroot =~ s/\/$//;
        $file =~ s/\\/\//g;
        my $list_file = $buildroot.'/'.$list;
        -f $list_file || return undef;
        my $path = $buildroot.'/'.$file;
        -f $path || return undef;
        unlink($path) || return undef;
        open (LST,$list_file) || return undef;
        my $found = 0;
        my @list_buf;
        while(<LST>){
                chomp;
                /\S/ or next;
                /"$file"/ or  $found = 1 and next
                push @list_buf,$_;
        }
        close(LST);
        return undef unless $found;
        open (LST,'>'.$list_file) || return undef;
        foreach ( @list_buf){
                print LST "$_\n";
        }
        close(LST);
        return 1;
}

sub do_cmd{
        my ($cmd) = @_;
        msg("processing $cmd\n");
        my $outtxt = `$cmd 2>&1`;
        if($? != 0){
                err("$cmd: $outtxt\n");
                return;
        }
        return 1;
}

sub deltree{
        my ($dir) = @_;
        -d $dir || return 0;
        opendir(DH,$dir) || return 0;
        my @content = readdir(DH);
        close(DH);

        my @files = grep { -f "$dir/$_" } @content;
        my @dirs = grep { -d "$dir/$_" && ! /^\.{1,2}$/} @content;

        foreach (@dirs){
                -l "$dir/$_" and next;
                deltree("$dir/$_") || return 0;
        }
        foreach (@files){
                -l "$dir/$_" and next;
		    -f "$dir/$_" and (unlink("$dir/$_") or err("cannot delete $dir/$_\n") and return 0);
        }
        rmdir($dir) or err("cannot delete $dir\n") and return 0;
        return 1;
}


sub makedir{
        my ($dir,$mode) = @_;
        $dir =~ s/\\/\//g;
        $dir =~ s/\/$//;
        -d $dir && return 1;
        my ($parent) = ($dir =~ /^(.*)\/[^\/]+$/);
        if($dir !~ /\// || -d $parent){
                mkdir($dir,$mode) || return 0;
                unless($^O =~ /mswin/i){
					#
					# workaround for perl bug
					#
					my @statbuf = stat ($dir);
					my $filemode = $statbuf[2] & 0777;
					if ($filemode != $mode) {
						chmod ($mode, $dir) || return 0;
					}
				}
				return 1;
        }
        makedir($parent,$mode) || return 0;
        mkdir($dir,$mode) || return 0;
		unless($^O =~ /mswin/i){
			#
			# workaround for perl bug
			#
			my @statbuf = stat ($dir);
			my $filemode = $statbuf[2] & 0777;
			if ($filemode != $mode) {
				chmod ($mode, $dir) || return 0;
			}
		}
		
		return 1;
}

sub find {
        my ($dir,$type) = @_;
        my @returnvalue;
        -d $dir or return undef;
        opendir(DH,$dir) || return undef;
        my @content = readdir(DH);
        close(DH);

        my @files = grep { -f "$dir/$_" } @content;
        my @dirs = grep { -d "$dir/$_" && ! /^\.{1,2}$/} @content;


        foreach(@dirs){
                -l "$dir/$_" and next;
                my @result = find("$dir/$_",$type);
                defined @result && push @returnvalue,@result;
        }

        if($type !~ /^d$/i){
                foreach (@files){
                        push @returnvalue,"$dir/$_";
                }
        }
        if($type !~ /^f$/i){
                foreach (@dirs){
                        push @returnvalue,"$dir/$_";
                }
        }
        return @returnvalue;
}




1;






