Archive-Unrar

 view release on metacpan or  search on metacpan

lib/Archive/Unrar.pm  view on Meta::CPAN


	unless ($flagsEX & 128){
		if ($RAR_functions{RARReadHeader}->Call( $handle, $RARHeaderData_struct )) {
				!$RAR_functions{RARCloseArchive}->Call($handle) || die "Fatal error $!";		
				return (undef,undef,ERAR_READ_HEADER);
		}
		else
		{	 
			( $arcname, $filename, $flags ) =  unpack( 'Z260Z260L', $RARHeaderData_struct );
			$arcname  =~s/\0//g;
			$filename =~s/\0//g;
		}
	}
	
	printf( "\nFile:    %s\n", $file );
	printf( "\nArchive: %s\n", $arcname );
		
		#transcoding
		my $filename=decode($OEM_CP,$filename);	
		my $filename=encode($ANSI_CP,$filename);	
		printf( "\n(First)Internal Filename: %s\n", $filename );
		
	printf( "\nPassword?:\t%s", 
	      ($flagsEX & 128)? "yes" :( $flags & 4 )     ? "yes" : "no" ); 
    printf( "\nVolume:\t\t%s",     ( $flagsEX & 1 )   ? "yes" : "no" );
    printf( "\nComment:\t%s",      ( $flagsEX & 2 )   ? "yes" : "no" );
    printf( "\nLocked:\t\t%s",     ( $flagsEX & 4 )   ? "yes" : "no" );
    printf( "\nSolid:\t\t%s",      ( $flagsEX & 8 )   ? "yes" : "no" );
    printf( "\nNew naming:\t%s",   ( $flagsEX & 16 )  ? "yes" : "no" );
    printf( "\nAuthenticity:\t%s", ( $flagsEX & 32 )  ? "yes" : "no" );
    printf( "\nRecovery:\t%s",     ( $flagsEX & 64 )  ? "yes" : "no" );
    printf( "\nEncr.headers:\t%s", ( $flagsEX & 128 ) ? "yes" : "no" );
    printf( "\nFirst volume:\t%s\n\n",
        ( $flagsEX & 256 ) ? "yes" : "no or older than 3.0" );

	if ($CmtState==1) {
			$CmtBuf1 = unpack( 'A' . $CmtSize, $CmtBuf1 );
			#there might be more than 16K wide comments but we print only the first 16K
			printf( "\nEmbedded Archive Comments (limited to first 16K) : <<<< %s", $CmtBuf1. " >>>>\n" );
		}
	
    if ( exists $donotprocess{$file} ) {
	    #found in the cache which means that the multipart archive has already been extracted.so not need to process this file 
        $continue = ERAR_CHAIN_FOUND;		
    } 
	elsif (!($flagsEX & 256) && !($flagsEX & 128) && ($flagsEX & 1)) {
            #if file is not blockencrypted and is not the first volume of a multi part archive
			#we do not need to process it
            $continue=ERAR_MULTI_BRK;
		}
	  		
   !$RAR_functions{RARCloseArchive}->Call($handle) || die "Fatal error $!";

  return ( $flagsEX & 128, $flags & 4 , $continue);
}

################ PUBLIC METHODS ################ 

sub list_files_in_archive {
	
   my $caller_sub = ( caller(1) )[3];
   my %params=@_;

	my ($file,$password) = @params{qw (file password)};
	
    my ( $blockencrypted, $pass_req, $continue ) = extract_headers($file);
	
    my $blockencryptedflag;
	my $errorcode;

	my %RAR_functions;
	declare_win32_functions(\%RAR_functions);
	
	my $RAROpenArchiveDataEx_struct =
      pack( 'pLLLPLLLLL32', $file, 0, 2, 0, undef, 0, 0, 0, 0,0 );
	   	     
    my $handle = $RAR_functions{RAROpenArchiveEx}->Call($RAROpenArchiveDataEx_struct);
        	
	if ($handle == 0 ) {
	 return ERAR_WRONG_FORMAT;
	 }
	 
      
	my $RARHeaderData_struct = pack( 'x260x260LLLLLLLLLLPLLL',
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undef, 0, 0, 0 );
			
	 

     if ($blockencrypted) { 

         if ($password) {
             $RAR_functions{RARSetPassword}->Call( $handle, $password );
         }
         else {
			 !$RAR_functions{RARCloseArchive}->Call($handle) || die "Fatal error $!";
				 return ERAR_MISSING_PASSWORD;
         }
     }
	 elsif ($pass_req) {
	 
		    $RAR_functions{RARSetPassword}->Call( $handle, $password );
	 }

    while ( ( $RAR_functions{RARReadHeader}->Call( $handle, $RARHeaderData_struct ) ) == 0 ) {
	    $blockencryptedflag="yes";
        
		my $processresult = $RAR_functions{RARProcessFile}->Call( $handle, 0, 0, 0 );
        
		if ( $processresult != 0 ) {
            $errorcode=$processresult; 
            last;
        }
        else {	    
            my @files = unpack( 'Z260Z260', $RARHeaderData_struct );
			$files[0] =~  s/\0//g;
           	$donotprocess{ $files[0] } = 1;
			
			#Look up the stack and see who has called "list_files_in_archive"
			#if it is not "process_file" then print the contents of the current file on STDOUT.
			#This is done because "process_file" calls "list_files_in_archive"
			#for its own purposes (caching files); it is not interested in printing



( run in 1.675 second using v1.01-cache-2.11-cpan-6de40a662fe )