#!perl -w # (C) 2003-2007 Willem Jan Hengeveld # Web: http://www.xs4all.nl/~itsme/ # http://wiki.xda-developers.com/ # # $Id$ # use strict; use IO::File; if (!@ARGV) { die "Usage: \n"; } my $cfgfile= shift; my $directory= shift; my $operatorimg= shift; if (!-d $directory) { die "$directory does not exists or is not a directory\n"; } my $config= ReadConfig($cfgfile); VerifyCustomFiles($config, "$directory/customid.dat", "$directory/customtab.dat"); WriteImage($config, $directory, $operatorimg); exit(0); sub ReadConfig { my ($fn)= @_; my $fh= IO::File->new($fn, "r") or die "$fn: $!\n"; my @config; while(<$fh>) { s/[\r\n]+$//; if (/^(.*?)\s*=\s*(.*?)(?:\s*=\s*(.*?)\s*=\s*(.*?))?$/) { my ($localname, $storedpath, $storedname, $configid) = ($1, $2, $3, $4); $storedname ||= $localname; $configid ||= "0"; push @config, { localname=>$localname, storedpath=>$storedpath, storedname=>$storedname, configid=>$configid, }; } } $fh->close(); return \@config; } sub WriteImage { my ($config, $directory, $operatorimg)= @_; my $img= IO::File->new($operatorimg, "w") or die "$operatorimg: $!\n"; binmode $img; $img->print(pack("LLL", 0x34798243, 0x00001001, 0x00000000)); my $ofs= 0; for (@$config) { $img->print($_->{storedpath}, "\\", $_->{storedname}, "\000"); my $filesize= -s "$directory/$_->{localname}"; if (!defined $filesize) { die "error getting filesize for $directory/$_->{localname}\n"; } $img->print(pack("LL", $ofs, $filesize)); $img->print($_->{configid}, "\000"); $ofs += $filesize; } $img->print("\xff" x (16384-$img->tell())); for (@$config) { my $in= IO::File->new("$directory/$_->{localname}", "r") or die "$directory/$_->{localname}: $!\n"; binmode $in; my $filedata; while (!$in->eof) { $in->read($filedata, 65536); $img->print($filedata); } $in->close(); } $img->close(); } sub VerifyCustomFiles { my ($config, $idfile, $tabfile)= @_; local $/="\x00"; my $customid; # verify customid.dat my $fh= IO::File->new($idfile, "r"); binmode $fh; while (<$fh>) { s/\x00$//; if (!defined $customid) { $customid= $_; } else { die "customid.dat is too large\n"; } } $fh->close(); # verify customtab.dat $fh= IO::File->new($tabfile, "r"); binmode $fh; my $i= 0; my @tab; my $line= []; while (<$fh>) { s/\x00$//; push @$line, $_; $i++; if ($i == 3) { push @tab, $line; $line= []; $i= 0; } } $fh->close(); if ($i!=0) { die "Incorrect nr of items in tab file\n"; } # check if all entries have the correct customid if (grep { $_->[0] ne $customid } @tab) { die "not all tab entries have customid $customid\n"; } # check if all entries have files, this is not an error, just warn. my %cfgids; $cfgids{$_->{configid}}++ for (@$config); my @nofiles= grep { !exists $cfgids{$_->[1]} || !defined $cfgids{$_->[1]} || $cfgids{$_->[1]}==0 } @tab; if (@nofiles) { warn "no files for configid ", join(" ", map { $_->[1] } @nofiles), "\n"; } }