1#!/usr/bin/perl 2# DVB firmware extractor 3# 4# (c) 2004 Andrew de Quincey 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, write to the Free Software 19# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 21use File::Temp qw/ tempdir /; 22use IO::Handle; 23 24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", 25 "tda10046lifeview", "av7110", "dec2000t", "dec2540t", 26 "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", 27 "or51211", "or51132_qam", "or51132_vsb", "bluebird", 28 "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", 29 "af9015", "ngene", "az6027"); 30 31# Check args 32syntax() if (scalar(@ARGV) != 1); 33$cid = $ARGV[0]; 34 35# Do it! 36for ($i=0; $i < scalar(@components); $i++) { 37 if ($cid eq $components[$i]) { 38 $outfile = eval($cid); 39 die $@ if $@; 40 print STDERR <<EOF; 41Firmware(s) $outfile extracted successfully. 42Now copy it(them) to either /usr/lib/hotplug/firmware or /lib/firmware 43(depending on configuration of firmware hotplug). 44EOF 45 exit(0); 46 } 47} 48 49# If we get here, it wasn't found 50print STDERR "Unknown component \"$cid\"\n"; 51syntax(); 52 53 54 55 56# --------------------------------------------------------------- 57# Firmware-specific extraction subroutines 58 59sub sp8870 { 60 my $sourcefile = "tt_Premium_217g.zip"; 61 my $url = "http://www.softwarepatch.pl/9999ccd06a4813cb827dbb0005071c71/$sourcefile"; 62 my $hash = "53970ec17a538945a6d8cb608a7b3899"; 63 my $outfile = "dvb-fe-sp8870.fw"; 64 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 65 66 checkstandard(); 67 68 wgetfile($sourcefile, $url); 69 unzip($sourcefile, $tmpdir); 70 verify("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $hash); 71 copy("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $outfile); 72 73 $outfile; 74} 75 76sub sp887x { 77 my $sourcefile = "Dvbt1.3.57.6.zip"; 78 my $url = "http://www.avermedia.com/software/$sourcefile"; 79 my $cabfile = "DVBT Net Ver1.3.57.6/disk1/data1.cab"; 80 my $hash = "237938d53a7f834c05c42b894ca68ac3"; 81 my $outfile = "dvb-fe-sp887x.fw"; 82 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 83 84 checkstandard(); 85 checkunshield(); 86 87 wgetfile($sourcefile, $url); 88 unzip($sourcefile, $tmpdir); 89 unshield("$tmpdir/$cabfile", $tmpdir); 90 verify("$tmpdir/ZEnglish/sc_main.mc", $hash); 91 copy("$tmpdir/ZEnglish/sc_main.mc", $outfile); 92 93 $outfile; 94} 95 96sub tda10045 { 97 my $sourcefile = "tt_budget_217g.zip"; 98 my $url = "http://www.technotrend.de/new/217g/$sourcefile"; 99 my $hash = "2105fd5bf37842fbcdfa4bfd58f3594a"; 100 my $outfile = "dvb-fe-tda10045.fw"; 101 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 102 103 checkstandard(); 104 105 wgetfile($sourcefile, $url); 106 unzip($sourcefile, $tmpdir); 107 extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x37ef9, 30555, "$tmpdir/fwtmp"); 108 verify("$tmpdir/fwtmp", $hash); 109 copy("$tmpdir/fwtmp", $outfile); 110 111 $outfile; 112} 113 114sub tda10046 { 115 my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip"; 116 my $url = "http://www.tt-download.com/download/updates/219/$sourcefile"; 117 my $hash = "6a7e1e2f2644b162ff0502367553c72d"; 118 my $outfile = "dvb-fe-tda10046.fw"; 119 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 120 121 checkstandard(); 122 123 wgetfile($sourcefile, $url); 124 unzip($sourcefile, $tmpdir); 125 extract("$tmpdir/TT_PCI_2.19h_28_11_2006/software/OEM/PCI/App/ttlcdacc.dll", 0x65389, 24478, "$tmpdir/fwtmp"); 126 verify("$tmpdir/fwtmp", $hash); 127 copy("$tmpdir/fwtmp", $outfile); 128 129 $outfile; 130} 131 132sub tda10046lifeview { 133 my $sourcefile = "7%5Cdrv_2.11.02.zip"; 134 my $url = "http://www.lifeview.hk/dbimages/document/$sourcefile"; 135 my $hash = "1ea24dee4eea8fe971686981f34fd2e0"; 136 my $outfile = "dvb-fe-tda10046.fw"; 137 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 138 139 checkstandard(); 140 141 wgetfile($sourcefile, $url); 142 unzip($sourcefile, $tmpdir); 143 extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp"); 144 verify("$tmpdir/fwtmp", $hash); 145 copy("$tmpdir/fwtmp", $outfile); 146 147 $outfile; 148} 149 150sub av7110 { 151 my $sourcefile = "dvb-ttpci-01.fw-261d"; 152 my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile"; 153 my $hash = "603431b6259715a8e88f376a53b64e2f"; 154 my $outfile = "dvb-ttpci-01.fw"; 155 156 checkstandard(); 157 158 wgetfile($sourcefile, $url); 159 verify($sourcefile, $hash); 160 copy($sourcefile, $outfile); 161 162 $outfile; 163} 164 165sub dec2000t { 166 my $sourcefile = "dec217g.exe"; 167 my $url = "http://hauppauge.lightpath.net/de/$sourcefile"; 168 my $hash = "bd86f458cee4a8f0a8ce2d20c66215a9"; 169 my $outfile = "dvb-ttusb-dec-2000t.fw"; 170 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 171 172 checkstandard(); 173 174 wgetfile($sourcefile, $url); 175 unzip($sourcefile, $tmpdir); 176 verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $hash); 177 copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $outfile); 178 179 $outfile; 180} 181 182sub dec2540t { 183 my $sourcefile = "dec217g.exe"; 184 my $url = "http://hauppauge.lightpath.net/de/$sourcefile"; 185 my $hash = "53e58f4f5b5c2930beee74a7681fed92"; 186 my $outfile = "dvb-ttusb-dec-2540t.fw"; 187 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 188 189 checkstandard(); 190 191 wgetfile($sourcefile, $url); 192 unzip($sourcefile, $tmpdir); 193 verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $hash); 194 copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $outfile); 195 196 $outfile; 197} 198 199sub dec3000s { 200 my $sourcefile = "dec217g.exe"; 201 my $url = "http://hauppauge.lightpath.net/de/$sourcefile"; 202 my $hash = "b013ececea83f4d6d8d2a29ac7c1b448"; 203 my $outfile = "dvb-ttusb-dec-3000s.fw"; 204 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 205 206 checkstandard(); 207 208 wgetfile($sourcefile, $url); 209 unzip($sourcefile, $tmpdir); 210 verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $hash); 211 copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $outfile); 212 213 $outfile; 214} 215sub opera1{ 216 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0); 217 218 checkstandard(); 219 my $fwfile1="dvb-usb-opera1-fpga-01.fw"; 220 my $fwfile2="dvb-usb-opera-01.fw"; 221 extract("2830SCap2.sys", 0x62e8, 55024, "$tmpdir/opera1-fpga.fw"); 222 extract("2830SLoad2.sys",0x3178,0x3685-0x3178,"$tmpdir/fw1part1"); 223 extract("2830SLoad2.sys",0x0980,0x3150-0x0980,"$tmpdir/fw1part2"); 224 delzero("$tmpdir/fw1part1","$tmpdir/fw1part1-1"); 225 delzero("$tmpdir/fw1part2","$tmpdir/fw1part2-1"); 226 verify("$tmpdir/fw1part1-1","5e0909858fdf0b5b09ad48b9fe622e70"); 227 verify("$tmpdir/fw1part2-1","d6e146f321427e931df2c6fcadac37a1"); 228 verify("$tmpdir/opera1-fpga.fw","0f8133f5e9051f5f3c1928f7e5a1b07d"); 229 230 my $RES1="\x01\x92\x7f\x00\x01\x00"; 231 my $RES0="\x01\x92\x7f\x00\x00\x00"; 232 my $DAT1="\x01\x00\xe6\x00\x01\x00"; 233 my $DAT0="\x01\x00\xe6\x00\x00\x00"; 234 open FW,">$tmpdir/opera.fw"; 235 print FW "$RES1"; 236 print FW "$DAT1"; 237 print FW "$RES1"; 238 print FW "$DAT1"; 239 appendfile(FW,"$tmpdir/fw1part1-1"); 240 print FW "$RES0"; 241 print FW "$DAT0"; 242 print FW "$RES1"; 243 print FW "$DAT1"; 244 appendfile(FW,"$tmpdir/fw1part2-1"); 245 print FW "$RES1"; 246 print FW "$DAT1"; 247 print FW "$RES0"; 248 print FW "$DAT0"; 249 copy ("$tmpdir/opera1-fpga.fw",$fwfile1); 250 copy ("$tmpdir/opera.fw",$fwfile2); 251 252 $fwfile1.",".$fwfile2; 253} 254 255sub vp7041 { 256 my $sourcefile = "2.422.zip"; 257 my $url = "http://www.twinhan.com/files/driver/USB-Ter/$sourcefile"; 258 my $hash = "e88c9372d1f66609a3e7b072c53fbcfe"; 259 my $outfile = "dvb-vp7041-2.422.fw"; 260 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 261 262 checkstandard(); 263 264 wgetfile($sourcefile, $url); 265 unzip($sourcefile, $tmpdir); 266 extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 12503, 3036, "$tmpdir/fwtmp1"); 267 extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 2207, 10274, "$tmpdir/fwtmp2"); 268 269 my $CMD = "\000\001\000\222\177\000"; 270 my $PAD = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; 271 my ($FW); 272 open $FW, ">$tmpdir/fwtmp3"; 273 print $FW "$CMD\001$PAD"; 274 print $FW "$CMD\001$PAD"; 275 appendfile($FW, "$tmpdir/fwtmp1"); 276 print $FW "$CMD\000$PAD"; 277 print $FW "$CMD\001$PAD"; 278 appendfile($FW, "$tmpdir/fwtmp2"); 279 print $FW "$CMD\001$PAD"; 280 print $FW "$CMD\000$PAD"; 281 close($FW); 282 283 verify("$tmpdir/fwtmp3", $hash); 284 copy("$tmpdir/fwtmp3", $outfile); 285 286 $outfile; 287} 288 289sub dibusb { 290 my $url = "http://www.linuxtv.org/downloads/firmware/dvb-usb-dibusb-5.0.0.11.fw"; 291 my $outfile = "dvb-dibusb-5.0.0.11.fw"; 292 my $hash = "fa490295a527360ca16dcdf3224ca243"; 293 294 checkstandard(); 295 296 wgetfile($outfile, $url); 297 verify($outfile,$hash); 298 299 $outfile; 300} 301 302sub nxt2002 { 303 my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip"; 304 my $url = "http://www.bbti.us/download/windows/$sourcefile"; 305 my $hash = "476befae8c7c1bb9648954060b1eec1f"; 306 my $outfile = "dvb-fe-nxt2002.fw"; 307 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 308 309 checkstandard(); 310 311 wgetfile($sourcefile, $url); 312 unzip($sourcefile, $tmpdir); 313 verify("$tmpdir/SkyNET.sys", $hash); 314 extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile); 315 316 $outfile; 317} 318 319sub nxt2004 { 320 my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip"; 321 my $url = "http://www.avermedia-usa.com/support/Drivers/$sourcefile"; 322 my $hash = "111cb885b1e009188346d72acfed024c"; 323 my $outfile = "dvb-fe-nxt2004.fw"; 324 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 325 326 checkstandard(); 327 328 wgetfile($sourcefile, $url); 329 unzip($sourcefile, $tmpdir); 330 verify("$tmpdir/3xHybrid.sys", $hash); 331 extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile); 332 333 $outfile; 334} 335 336sub or51211 { 337 my $fwfile = "dvb-fe-or51211.fw"; 338 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 339 my $hash = "d830949c771a289505bf9eafc225d491"; 340 341 checkstandard(); 342 343 wgetfile($fwfile, $url); 344 verify($fwfile, $hash); 345 346 $fwfile; 347} 348 349sub cx231xx { 350 my $fwfile = "v4l-cx231xx-avcore-01.fw"; 351 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 352 my $hash = "7d3bb956dc9df0eafded2b56ba57cc42"; 353 354 checkstandard(); 355 356 wgetfile($fwfile, $url); 357 verify($fwfile, $hash); 358 359 $fwfile; 360} 361 362sub cx18 { 363 my $url = "http://linuxtv.org/downloads/firmware/"; 364 365 my %files = ( 366 'v4l-cx23418-apu.fw' => '588f081b562f5c653a3db1ad8f65939a', 367 'v4l-cx23418-cpu.fw' => 'b6c7ed64bc44b1a6e0840adaeac39d79', 368 'v4l-cx23418-dig.fw' => '95bc688d3e7599fd5800161e9971cc55', 369 ); 370 371 checkstandard(); 372 373 my $allfiles; 374 foreach my $fwfile (keys %files) { 375 wgetfile($fwfile, "$url/$fwfile"); 376 verify($fwfile, $files{$fwfile}); 377 $allfiles .= " $fwfile"; 378 } 379 380 $allfiles =~ s/^\s//; 381 382 $allfiles; 383} 384 385sub mpc718 { 386 my $archive = 'Yuan MPC718 TV Tuner Card 2.13.10.1016.zip'; 387 my $url = "ftp://ftp.work.acer-euro.com/desktop/aspire_idea510/vista/Drivers/$archive"; 388 my $fwfile = "dvb-cx18-mpc718-mt352.fw"; 389 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 390 391 checkstandard(); 392 wgetfile($archive, $url); 393 unzip($archive, $tmpdir); 394 395 my $sourcefile = "$tmpdir/Yuan MPC718 TV Tuner Card 2.13.10.1016/mpc718_32bit/yuanrap.sys"; 396 my $found = 0; 397 398 open IN, '<', $sourcefile or die "Couldn't open $sourcefile to extract $fwfile data\n"; 399 binmode IN; 400 open OUT, '>', $fwfile; 401 binmode OUT; 402 { 403 # Block scope because we change the line terminator variable $/ 404 my $prevlen = 0; 405 my $currlen; 406 407 # Buried in the data segment are 3 runs of almost identical 408 # register-value pairs that end in 0x5d 0x01 which is a "TUNER GO" 409 # command for the MT352. 410 # Pull out the middle run (because it's easy) of register-value 411 # pairs to make the "firmware" file. 412 413 local $/ = "\x5d\x01"; # MT352 "TUNER GO" 414 415 while (<IN>) { 416 $currlen = length($_); 417 if ($prevlen == $currlen && $currlen <= 64) { 418 chop; chop; # Get rid of "TUNER GO" 419 s/^\0\0//; # get rid of leading 00 00 if it's there 420 printf OUT "$_"; 421 $found = 1; 422 last; 423 } 424 $prevlen = $currlen; 425 } 426 } 427 close OUT; 428 close IN; 429 if (!$found) { 430 unlink $fwfile; 431 die "Couldn't find valid register-value sequence in $sourcefile for $fwfile\n"; 432 } 433 $fwfile; 434} 435 436sub cx23885 { 437 my $url = "http://linuxtv.org/downloads/firmware/"; 438 439 my %files = ( 440 'v4l-cx23885-avcore-01.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb', 441 'v4l-cx23885-enc.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb', 442 ); 443 444 checkstandard(); 445 446 my $allfiles; 447 foreach my $fwfile (keys %files) { 448 wgetfile($fwfile, "$url/$fwfile"); 449 verify($fwfile, $files{$fwfile}); 450 $allfiles .= " $fwfile"; 451 } 452 453 $allfiles =~ s/^\s//; 454 455 $allfiles; 456} 457 458sub pvrusb2 { 459 my $url = "http://linuxtv.org/downloads/firmware/"; 460 461 my %files = ( 462 'v4l-cx25840.fw' => 'dadb79e9904fc8af96e8111d9cb59320', 463 ); 464 465 checkstandard(); 466 467 my $allfiles; 468 foreach my $fwfile (keys %files) { 469 wgetfile($fwfile, "$url/$fwfile"); 470 verify($fwfile, $files{$fwfile}); 471 $allfiles .= " $fwfile"; 472 } 473 474 $allfiles =~ s/^\s//; 475 476 $allfiles; 477} 478 479sub or51132_qam { 480 my $fwfile = "dvb-fe-or51132-qam.fw"; 481 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 482 my $hash = "7702e8938612de46ccadfe9b413cb3b5"; 483 484 checkstandard(); 485 486 wgetfile($fwfile, $url); 487 verify($fwfile, $hash); 488 489 $fwfile; 490} 491 492sub or51132_vsb { 493 my $fwfile = "dvb-fe-or51132-vsb.fw"; 494 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 495 my $hash = "c16208e02f36fc439a557ad4c613364a"; 496 497 checkstandard(); 498 499 wgetfile($fwfile, $url); 500 verify($fwfile, $hash); 501 502 $fwfile; 503} 504 505sub bluebird { 506 my $url = "http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw"; 507 my $outfile = "dvb-usb-bluebird-01.fw"; 508 my $hash = "658397cb9eba9101af9031302671f49d"; 509 510 checkstandard(); 511 512 wgetfile($outfile, $url); 513 verify($outfile,$hash); 514 515 $outfile; 516} 517 518sub af9015 { 519 my $sourcefile = "download.ashx?file=57"; 520 my $url = "http://www.ite.com.tw/EN/Services/$sourcefile"; 521 my $hash = "e3f08935158038d385ad382442f4bb2d"; 522 my $outfile = "dvb-usb-af9015.fw"; 523 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 524 my $fwoffset = 0x25690; 525 my $fwlength = 18725; 526 my ($chunklength, $buf, $rcount); 527 528 checkstandard(); 529 530 wgetfile($sourcefile, $url); 531 unzip($sourcefile, $tmpdir); 532 verify("$tmpdir/Driver/Files/AF15BDA.sys", $hash); 533 534 open INFILE, '<', "$tmpdir/Driver/Files/AF15BDA.sys"; 535 open OUTFILE, '>', $outfile; 536 537 sysseek(INFILE, $fwoffset, SEEK_SET); 538 while($fwlength > 0) { 539 $chunklength = 55; 540 $chunklength = $fwlength if ($chunklength > $fwlength); 541 $rcount = sysread(INFILE, $buf, $chunklength); 542 die "Ran out of data\n" if ($rcount != $chunklength); 543 syswrite(OUTFILE, $buf); 544 sysread(INFILE, $buf, 8); 545 $fwlength -= $rcount + 8; 546 } 547 548 close OUTFILE; 549 close INFILE; 550} 551 552sub ngene { 553 my $url = "http://www.digitaldevices.de/download/"; 554 my $file1 = "ngene_15.fw"; 555 my $hash1 = "d798d5a757121174f0dbc5f2833c0c85"; 556 my $file2 = "ngene_17.fw"; 557 my $hash2 = "26b687136e127b8ac24b81e0eeafc20b"; 558 559 checkstandard(); 560 561 wgetfile($file1, $url . $file1); 562 verify($file1, $hash1); 563 564 wgetfile($file2, $url . $file2); 565 verify($file2, $hash2); 566 567 "$file1, $file2"; 568} 569 570sub az6027{ 571 my $file = "AZ6027_Linux_Driver.tar.gz"; 572 my $url = "http://linux.terratec.de/files/$file"; 573 my $firmware = "dvb-usb-az6027-03.fw"; 574 575 wgetfile($file, $url); 576 577 #untar 578 if( system("tar xzvf $file $firmware")){ 579 die "failed to untar firmware"; 580 } 581 if( system("rm $file")){ 582 die ("unable to remove unnecessary files"); 583 } 584 585 $firmware; 586} 587# --------------------------------------------------------------- 588# Utilities 589 590sub checkstandard { 591 if (system("which unzip > /dev/null 2>&1")) { 592 die "This firmware requires the unzip command - see ftp://ftp.info-zip.org/pub/infozip/UnZip.html\n"; 593 } 594 if (system("which md5sum > /dev/null 2>&1")) { 595 die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n"; 596 } 597 if (system("which wget > /dev/null 2>&1")) { 598 die "This firmware requires the wget command - see http://wget.sunsite.dk/\n"; 599 } 600} 601 602sub checkunshield { 603 if (system("which unshield > /dev/null 2>&1")) { 604 die "This firmware requires the unshield command - see http://sourceforge.net/projects/synce/\n"; 605 } 606} 607 608sub wgetfile { 609 my ($sourcefile, $url) = @_; 610 611 if (! -f $sourcefile) { 612 system("wget -O \"$sourcefile\" \"$url\"") and die "wget failed - unable to download firmware"; 613 } 614} 615 616sub unzip { 617 my ($sourcefile, $todir) = @_; 618 619 $status = system("unzip -q -o -d \"$todir\" \"$sourcefile\" 2>/dev/null" ); 620 if ((($status >> 8) > 2) || (($status & 0xff) != 0)) { 621 die ("unzip failed - unable to extract firmware"); 622 } 623} 624 625sub unshield { 626 my ($sourcefile, $todir) = @_; 627 628 system("unshield x -d \"$todir\" \"$sourcefile\" > /dev/null" ) and die ("unshield failed - unable to extract firmware"); 629} 630 631sub verify { 632 my ($filename, $hash) = @_; 633 my ($testhash); 634 635 open(CMD, "md5sum \"$filename\"|"); 636 $testhash = <CMD>; 637 $testhash =~ /([a-zA-Z0-9]*)/; 638 $testhash = $1; 639 close CMD; 640 die "Hash of extracted file does not match!\n" if ($testhash ne $hash); 641} 642 643sub copy { 644 my ($from, $to) = @_; 645 646 system("cp -f \"$from\" \"$to\"") and die ("cp failed"); 647} 648 649sub extract { 650 my ($infile, $offset, $length, $outfile) = @_; 651 my ($chunklength, $buf, $rcount); 652 653 open INFILE, "<$infile"; 654 open OUTFILE, ">$outfile"; 655 sysseek(INFILE, $offset, SEEK_SET); 656 while($length > 0) { 657 # Calc chunk size 658 $chunklength = 2048; 659 $chunklength = $length if ($chunklength > $length); 660 661 $rcount = sysread(INFILE, $buf, $chunklength); 662 die "Ran out of data\n" if ($rcount != $chunklength); 663 syswrite(OUTFILE, $buf); 664 $length -= $rcount; 665 } 666 close INFILE; 667 close OUTFILE; 668} 669 670sub appendfile { 671 my ($FH, $infile) = @_; 672 my ($buf); 673 674 open INFILE, "<$infile"; 675 while(1) { 676 $rcount = sysread(INFILE, $buf, 2048); 677 last if ($rcount == 0); 678 print $FH $buf; 679 } 680 close(INFILE); 681} 682 683sub delzero{ 684 my ($infile,$outfile) =@_; 685 686 open INFILE,"<$infile"; 687 open OUTFILE,">$outfile"; 688 while (1){ 689 $rcount=sysread(INFILE,$buf,22); 690 $len=ord(substr($buf,0,1)); 691 print OUTFILE substr($buf,0,1); 692 print OUTFILE substr($buf,2,$len+3); 693 last if ($rcount<1); 694 printf OUTFILE "%c",0; 695#print $len." ".length($buf)."\n"; 696 697 } 698 close(INFILE); 699 close(OUTFILE); 700} 701 702sub syntax() { 703 print STDERR "syntax: get_dvb_firmware <component>\n"; 704 print STDERR "Supported components:\n"; 705 @components = sort @components; 706 for($i=0; $i < scalar(@components); $i++) { 707 print STDERR "\t" . $components[$i] . "\n"; 708 } 709 exit(1); 710} 711