#!/usr/bin/perl -w use strict; my $filename_raw='f45015.zip'; my $debug=0; { my $zip_test='zip_status.txt'; system('unzip -t '.$filename_raw.' &> '.$zip_test); #unzip -t f45015.zip #Archive: f45015.zip #warning [f45015.zip]: 1536 extra bytes at beginning or within zipfile # (attempting to process anyway) #file #1: bad zipfile offset (local header sig): 1536 # (attempting to re-compensate) # testing: 1993-01-a-large_web.jpg OK # testing: 1995-45-a-large_web.jpg OK # testing: 2000-06-a-large_web.jpg OK # testing: 2000-07-a-large_web.jpg OK # testing: 2002-29-a-large_web.jpg # error: invalid compressed data to inflate #file #6: bad zipfile offset (local header sig): 214071 # (attempting to re-compensate) # testing: 2005-02-e-large_web.jpg OK #At least one error was detected in f45015.zip. my $extra_sectors=0; my $file_hs=0; my $err=0; open(IN, '<',$zip_test) or die("Can't open file $zip_test: $!\n"); while(my $line=) { if($line=~/(\d+) extra bytes at beginning or within zipfile/) { my $extra_bytes=$1; print "Can't repair file" if($extra_bytes%512!=0); $extra_sectors=int($extra_bytes/512); } $err=1 if($line=~/error:/); if($err) { if($line=~/file #(\d+):/) { $file_hs=$1; } } } close(IN); $file_hs--; if($debug>0) { print "extra_sectors $extra_sectors\n"; print "file_hs $file_hs\n"; } system('unzip -lv '.$filename_raw.' &> '.$zip_test); # unzip -lv f45015.zip #Archive: f45015.zip #warning [f45015.zip]: 1536 extra bytes at beginning or within zipfile # (attempting to process anyway) # Length Method Size Ratio Date Time CRC-32 Name #-------- ------ ------- ----- ---- ---- ------ ---- # 62179 Defl:N 62104 0% 05-09-06 04:35 5aed4c0d 1993-01-a-large_web.jpg # 37157 Defl:N 37045 0% 05-09-06 04:36 478c0fc8 1995-45-a-large_web.jpg # 44808 Defl:N 44761 0% 05-09-06 04:34 9fd5a0be 2000-06-a-large_web.jpg # 28740 Defl:N 27158 6% 05-09-06 04:35 719afc30 2000-07-a-large_web.jpg # 42629 Defl:N 42578 0% 05-09-06 04:35 460a300d 2002-29-a-large_web.jpg # 55610 Defl:N 55517 0% 05-09-06 04:35 5e9dd573 2005-02-e-large_web.jpg #-------- ------- --- ------- # 271123 269163 1% 6 files # # 62104+37045+44761+27158=171068 => 334 my $zip_start=0; open(IN, '<',$zip_test) or die("Can't open file $zip_test: $!\n"); while(my $line=) { if($line=~/\d+\s+\S+\s+(\d+)/) { $zip_start+=$1 if(--$file_hs>0); } } close(IN); $zip_start=int($zip_start/512); my $zip_end=int((-s $filename_raw)/512); if($debug>0) { print "zip_start $zip_start\n"; print "zip_end $zip_end\n"; } open(IN,'<',$filename_raw) or die("Can't open $filename_raw: $!\n"); { my $filename_tmp='test.zip'; my $err=9; my $offset; for($offset=$zip_start;$offset<$zip_end && $err!=0;$offset++) { open(OUT,'>',$filename_tmp) or die("Can't create $filename_tmp: $!\n"); my $len=1; for(my $sector=0;$len>0;$sector++) { my $buffer; if($sector>=$offset && $sector<$offset+$extra_sectors) { } else { sysseek(IN,512*$sector,0); $len=sysread(IN,$buffer,512); syswrite(OUT,$buffer); } } close(OUT); $err=0; system('unzip -t '.$filename_tmp.' > /dev/null 2> '.$zip_test); if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { $err=$? >> 8; } if( -s $zip_test > 0) { $err=1; } } if($err==0) { print "Found ".$extra_sectors." extra data 512-bytes block at block ".$offset."\n"; print "Fixed file is ".$filename_tmp."\n"; } } close(IN); }