Binary file .DS_Store has changed
Binary file scripts/.DS_Store has changed
--- a/scripts/gettd.pl Wed Jan 20 12:00:05 2010 +0000
+++ b/scripts/gettd.pl Wed Jan 27 10:52:27 2010 +0000
@@ -1,484 +1,484 @@
-#!/usr/bin/perl
-
-
-
-use IO::Socket;
-use Getopt::Long;
-
-
-my $target_url; #target url for the roadmap
-my $tdomain; #tag for the domain to be use in csv file
-my $csvfile; #output csv file name
-my $authon= ''; #does it require authorisation? default is false
-
-
-my $count_target; #this value is used to pass a string to match and count on each package backlog
-my $ispackage;
-my $splitbklogs;
-my $summaryheader="ID\tPackage\tFeatures\tFormat\tHttp\n" ;
-my $newtdformat = 0;
-my @blist = ("Tracking_Package_features","Kernel_EPLization_Backlog",
- "Package_Backlog_Q","Wishlist","Test_Package","Backlog_Details");
-
-
-sub blacklist
-{
- ($name)=@_;
-
- foreach(@blist) {
-
- if ( $name =~ m/$_/sg) { print "WARNING - $name is blacklisted\n"; return 1;}
- }
-
- return 0;
-
-}
-
-
-sub getpage
-{
- #arguments
- ($page,$host,$auth,$myfile)=@_;
-
-
- #output file
- open ( outputfile, ">".$myfile);
-
-
- $port = "http(80)";
- $getmess = "GET " . $page ." HTTP/1.1\n" . $auth;
-
- print "INFO - sending message - $getmess\n";
- print outputfile "$getmess\n\n";
-
- $sock = IO::Socket::INET->new
- (
- PeerAddr => $host, PeerPort => $port, Proto => 'tcp',
- ) ;
-
-
- print $sock "$getmess\n\n";
-
-
- while(<$sock>) {
-
- print outputfile $_;
-
- }
-
- close ($sock);
- close (outputfile);
-}
-
-sub prntfeatures
-{
-
- ($release,$package,$features,$myfile,$domain)=@_;
-
- $release =~ s/\\//sg;
- $csvdel ="\",\"";
- $invcoma ="\"";
- if ($newtdformat) {
- $package =~ s/backlog//sgi;
- print $myfile "$invcoma $release $csvdel $domain $csvdel $package $csvdel $myfeat $invcoma\n";
-
- } else {
-
- $features = $features."<dt";
-
-
-
- while ( $features =~ /dt\>(.*?)\<\/dt(.*?)\<dt/sg ){
- $myfeat = $1;
- $subfeat =$2;
-
- $myfeat =~ s/\n/ /sg;
-
- pos($features) = pos($features) -2;
-
- $mystr="";
- while ( $subfeat =~ /\<dd\>(.*?)\<\/dd\>/sg) {
- $mysubfeat = $mysubfeat.$mystr.$1;
- $mystr = " & ";
- }
- undef $mystr;
- $mysubfeat =~ s/,/ /sg;
- $mysubfeat =~ s/\n//sg;
- $mysubfeat =~ s/\<.*?\>//sg;
-
-
- print $myfile "$invcoma $release $csvdel $domain $csvdel $package $csvdel $myfeat $csvdel $csvdel $csvdel $mysubfeat $invcoma\n";
-
- $mysubfeat = "";
- }
-
- }
-}
-
-sub loadfile
-{
-
- $/ = " ";
- #arguments
- ($myfile)=@_;
- open ( inputfile, "<".$myfile);
- my $contents = do { local $/; <inputfile> };
- close(inputfile);
- return $contents;
-
-}
-
-sub td_roadmap
-{
-
-
- #arguments
- ($infile,$outfile,$domain,@releases)=@_;
-
-
- $roadmap=loadfile $infile;
- open ( outputfile, ">>".$outfile);
-
-
- if ($newtdformat) {
- print "Processing new TD roadmap format\n";
- if ($roadmap =~ m /Contents\<\/h2\>.*?\<\/table/sg) { $roadmap =$';}
- foreach (@releases) {
- $exp=$_." Roadmap";
-
- if ($roadmap =~ m /($exp)/sg) {
- print "PASS - Found entry for $_ \n";
- $relroad =$';
-
- if ($roadmap =~ m /table\>(.*?)\<\/table/sg) { $relroad =$1;}
- $relroad =~ s/\n//sg;
-
- $skipfirst =1; #skipping the header of the table
- while ($relroad =~ m/\<tr\>(.*?)\<\/tr(.*)/sg){
- $myfeat=$1;
- $relroad =$2;
- if ($skipfirst) {$skipfirst=0;next;}
- $package="";
- if ($myfeat =~ m/title\=\"(.*?)\"/sg) { $package=$1; } #looking for package name
-
- $myfeat=~ s/\<\/td\>\<td\>/\",\"/sg;
- $myfeat=~ s/\<.*?\>//sg;
-
- if ($myfeat =~m/[A-z]/sg ){prntfeatures($_,$package,$myfeat,outputfile,$domain);}
-
- }
- }
- }
- } else {
-
- foreach (@releases) {
-
- $exp="\\<h2\\>.*?\\>".$_;
-
- if ($roadmap =~ m /($exp)/sg) {
- print "PASS - Found entry for $_ \n";
- $relroad =$';
-
- if ($relroad =~ m /(.*?)\<h2/sg) { $relroad =$1;}
- $i=0;
- while ($relroad=~ m/\<h3\>.*\>(.*?)\<.*<\/h3/g) {
- $package = $1;
- $ppos[$i]= pos($relroad);
- $pname[$i]= $package;
- $i++;
- }
- for ( $i=0;$i<($#ppos); $i++){
- $features= substr ($relroad, $ppos[$i],$ppos[$i+1]-$ppos[$i]);
- prntfeatures($_,$pname[$i],$features,outputfile,$domain);
- }
- $features= substr ($relroad, $ppos[$i]);
-
- prntfeatures($_,$pname[$i],$features,outputfile,$domain);
- @ppos ="";
- @pname ="";
- undef ($features);
- }
- }
-
- }
-
-
-
- close (outputfile);
-
-
-}
-
-
-sub parse_category {
-
- #arguments
- ($infile)=@_;
-
- my @mylink;
-
- $mypage=loadfile $infile;
- $i=0;
- if ( $mypage =~ m/Pages in category(.*)\<\/table/sg) {
- print "INFO - Category page found\n";
- $mypage = $1;
-
- while ($mypage =~ m /\<a href\=\"(\/wiki\/index\.php\/.*?)\"/g) {
-
- $mylink[$i] = $1;
- $i++;
-
- }
- print "INFO - Found $i items in the category page\n"
- }
- return @mylink;
-}
-
-sub bklog_domain {
- #argument
-($mytechdomian)=@_;
-
- $mytechdomian =~s/\)//sg;
- $mytechdomian =~s/\(//sg;
-
- $domaininfo=loadfile ("package_domains.csv");
- if ($domaininfo =~ m/$mytechdomian.*?\{(.*?)\}/sgi ) {
- return $1;
- }
- print "ERROR - domain not found for $mytechdomian\n";
- return "orphan";
-
-}
-
-sub parse_bklog {
-
- #arguments
- ($infile,$outfile,$id)=@_;
- $mypkg=loadfile $infile;
- #list if the bklog has been ported to the new bugzilla based format
- $headerformat= "wiki_format";
-
-
- open ( outputfile, ">>".$outfile);
- open ( soutputfile, ">>"."summary_".$outfile);
-
- if ($mypkg =~ m/index\.php\/(.*?) HTTP/sg) {
-
- $pagename = $1;
-
- if ($splitbklogs) {
- $whichtd = bklog_domain($pagename);
- open ( tdoutputfile, ">>".$whichtd. "_".$outfile);
- }
-
-
-
- if (blacklist($pagename)) {
-
- close (outputfile);
- close (soutputfile);
-
- if ($splitbklogs) { close (tdoutputfile);}
- return 0;
- }
- print "INFO -Processing Package $pagename \n";
- $i=0;
- $found_counter =0;
-
- if ($mypkg =~m/class\=\"bugzilla sortable\"/sg ) { $headerformat="autobug_format"; }
-
- while ($mypkg =~ m/\<tr.*?\>(.*?)\<\/tr/sg) {
- $myheader= $&;
- if ($myheader =~ m/style=\"background-color\:/sg) {
- next;
- }
- $myfeat= $1;
- $myfeat =~ s/\<\/td\>/\t/sg;
- $myfeat =~ s/\<.*?\>//sg;
- $myfeat =~ s/\n//sg;
-
- if ($myfeat =~ m/IDPStatus/sg) { #header for bugzilla mediawiki plugin
- next;
- }
-
- if ($myfeat =~ m/[A-z]/sg and not $myfeat =~ m/\<\;etc/sg and
- not $myfeat =~ m/\<\;Feature/sg and not $myfeat =~ m/Item not available/sg) {
- print outputfile "$pagename\t$myfeat\n";
- if ($splitbklogs) { print tdoutputfile "$pagename\t$myfeat\n";}
-
- # print "matching $myfeat with $count_target\n" ;
- if ($myfeat =~ m/$count_target/sg) {$found_counter++;}
- $i++;
- }
-
- }
-
- if ($count_target){
- $mycount=$i."\t".$found_counter;
- } else {
- $mycount=$i;
- }
-
- if ($splitbklogs) {
- print soutputfile "$id\t$pagename\t$mycount\t$headerformat\t$whichtd\thttp://developer.symbian.org/wiki/index.php/$pagename\n";
- } else {
- print soutputfile "$id\t$pagename\t$mycount\t$headerformat\thttp://developer.symbian.org/wiki/index.php/$pagename\n";
- }
-
- }
-
- close (outputfile);
- close (soutputfile);
- if ($splitbklogs) { close (tdoutputfile);}
-
-}
-
-
-
-
-#help print
-sub printhelp
-{
-
- print "\n\n version 1.1
- \ngettd.pl -t=url -d=domain \n\nRequired parameters for Technology Roadmaps:\n\t -t url containing the technology domain roadmap\n\t -d the technology domain name
- \n\nOptional Parmeters for Technology Roadmaps\n\t-new if the roadmap has the new wiki format
- \n\nRequired Parameters for Package backlogs\n\t-p for package backlog analysis. just run gettd.pl -p
- \n\nOptional Pararmeters for Package backlogs\n\t -compare [f1] [f2] compares two package summary files for changes ignores order
- \n\t -split splits the content of the backlog output into technology domains. requires package_domains.csv file with mapping details
- \n\t -count=regexp counts the times that a package backlog line matches the regexp, the results are output to the summary file
- \n\nCommonOptional parameters\n\t-o filename ,the output is logged into the output.csv file by default\n\t-h for help
- \n\t recommend to run under cygwin environment and perl version v5.10.0 \n
- \n\t pages blacklisted for package backlogs are @blist\n";
- exit;
-}
-
-
-
-#compare bklogs
-sub compare_bklogs {
- #arguments
- (@bklogs)=@_;
-
- if (not $#bklogs == 1) { printhelp;}
-
-
- $cmd ="cut -f 2,3 ". $bklogs[0] . " | sort -u > tmp1.txt";
-
- system($cmd);
-
- $cmd ="cut -f 2,3 ". $bklogs[1] . " | sort -u > tmp2.txt";
- system($cmd);
-
- exec ("diff tmp1.txt tmp2.txt | grep '[<|>]'");
- system("rm temp*.txt");
-
- exit;
-
-}
-
-
-
-
-#process command line options
-sub cmd_options
-{
-
- my $help;
- my @compare;
-
-
- GetOptions('h' => \$help,'t=s'=> \$target_url, 'd=s' => \$tdomain , 'o=s' => \$csvfile,
- 'a' => \$authon , 'p' => \$ispackage, 'compare=s{2}' =>\@compare, 'new' => \$isnewformat,
- 'split' => \$splitbklogs, 'count=s' => \$count_target);
-
- if (@compare) {
- compare_bklogs @compare;
-
- }
- if ($count_target) {
- print "INFO - Seaching for $count_target\n";
- }
-
- if ($help) {
- printhelp;
- }
-
-
- if ($ispackage) {
-
- $tdomain =" ";
- $target_url = "http://developer.symbian.org/wiki/index.php/Category:Package_Backlog";
-
- }
- if ($isnewformat){
- $newtdformat = 1;
-
- }
-
- if ( not $target_url) {
-
- print "ERROR-missing arguments target url\n";
- printhelp;
- }
-
-
- if (not $tdomain){
- print "ERROR-missing arguments domain level\n";
- printhelp;
- }
-
- print "\nINFO-downloading $target_url with label $tdomain\n";
-
-
- if (not $csvfile) {
- if (not $ispackage) {
- $csvfile="output.csv";
-
- } else {
- $csvfile="output.txt";
- system ("rm *output.txt");
-
- }
- }
- print "\nINFO-output recorded in $csvfile \n";
-
-
-
-}
-#main
-$/ = " ";
-$host1 = "developer.symbian.org";
-
-cmd_options();
-
-if ($authon) {
- #file containing login details from http cookie
- $mycookie = loadfile("mycookie.txt");
-
- $auth = "Cookie: " . $mycookie ;
-}
-
-
-if ($ispackage) {
- getpage($target_url, $host1, $auth, "debug.txt");
- @bklog = parse_category("debug.txt");
- $j=0;
-
- foreach (@bklog) {
- getpage("http://".$host1.$_, $host1, $auth, "pkg".$j.".txt");
- parse_bklog ("pkg".$j.".txt",$csvfile, $j);
- $j++;
-
-
-
- }
-
-} else {
-
- #foundation releases - add as required
- @releases=("Symbian\\^2","Symbian\\^3","Symbian\\^4");
-
- getpage($target_url, $host1, $auth, "debug.txt");
- td_roadmap("debug.txt" , $csvfile, $tdomain ,@releases);
+#!/usr/bin/perl
+
+
+
+use IO::Socket;
+use Getopt::Long;
+
+
+my $target_url; #target url for the roadmap
+my $tdomain; #tag for the domain to be use in csv file
+my $csvfile; #output csv file name
+my $authon= ''; #does it require authorisation? default is false
+
+
+my $count_target; #this value is used to pass a string to match and count on each package backlog
+my $ispackage;
+my $splitbklogs;
+my $summaryheader="ID\tPackage\tFeatures\tFormat\tHttp\n" ;
+my $newtdformat = 0;
+my @blist = ("Tracking_Package_features","Kernel_EPLization_Backlog",
+ "Package_Backlog_Q","Wishlist","Test_Package","Backlog_Details");
+
+
+sub blacklist
+{
+ ($name)=@_;
+
+ foreach(@blist) {
+
+ if ( $name =~ m/$_/sg) { print "WARNING - $name is blacklisted\n"; return 1;}
+ }
+
+ return 0;
+
+}
+
+
+sub getpage
+{
+ #arguments
+ ($page,$host,$auth,$myfile)=@_;
+
+
+ #output file
+ open ( outputfile, ">".$myfile);
+
+
+ $port = "http(80)";
+ $getmess = "GET " . $page ." HTTP/1.1\n" . $auth;
+
+ print "INFO - sending message - $getmess\n";
+ print outputfile "$getmess\n\n";
+
+ $sock = IO::Socket::INET->new
+ (
+ PeerAddr => $host, PeerPort => $port, Proto => 'tcp',
+ ) ;
+
+
+ print $sock "$getmess\n\n";
+
+
+ while(<$sock>) {
+
+ print outputfile $_;
+
+ }
+
+ close ($sock);
+ close (outputfile);
+}
+
+sub prntfeatures
+{
+
+ ($release,$package,$features,$myfile,$domain)=@_;
+
+ $release =~ s/\\//sg;
+ $csvdel ="\",\"";
+ $invcoma ="\"";
+ if ($newtdformat) {
+ $package =~ s/backlog//sgi;
+ print $myfile "$invcoma $release $csvdel $domain $csvdel $package $csvdel $myfeat $invcoma\n";
+
+ } else {
+
+ $features = $features."<dt";
+
+
+
+ while ( $features =~ /dt\>(.*?)\<\/dt(.*?)\<dt/sg ){
+ $myfeat = $1;
+ $subfeat =$2;
+
+ $myfeat =~ s/\n/ /sg;
+
+ pos($features) = pos($features) -2;
+
+ $mystr="";
+ while ( $subfeat =~ /\<dd\>(.*?)\<\/dd\>/sg) {
+ $mysubfeat = $mysubfeat.$mystr.$1;
+ $mystr = " & ";
+ }
+ undef $mystr;
+ $mysubfeat =~ s/,/ /sg;
+ $mysubfeat =~ s/\n//sg;
+ $mysubfeat =~ s/\<.*?\>//sg;
+
+
+ print $myfile "$invcoma $release $csvdel $domain $csvdel $package $csvdel $myfeat $csvdel $csvdel $csvdel $mysubfeat $invcoma\n";
+
+ $mysubfeat = "";
+ }
+
+ }
+}
+
+sub loadfile
+{
+
+ $/ = " ";
+ #arguments
+ ($myfile)=@_;
+ open ( inputfile, "<".$myfile);
+ my $contents = do { local $/; <inputfile> };
+ close(inputfile);
+ return $contents;
+
+}
+
+sub td_roadmap
+{
+
+
+ #arguments
+ ($infile,$outfile,$domain,@releases)=@_;
+
+
+ $roadmap=loadfile $infile;
+ open ( outputfile, ">>".$outfile);
+
+
+ if ($newtdformat) {
+ print "Processing new TD roadmap format\n";
+ if ($roadmap =~ m /Contents\<\/h2\>.*?\<\/table/sg) { $roadmap =$';}
+ foreach (@releases) {
+ $exp=$_." Roadmap";
+
+ if ($roadmap =~ m /($exp)/sg) {
+ print "PASS - Found entry for $_ \n";
+ $relroad =$';
+
+ if ($roadmap =~ m /table\>(.*?)\<\/table/sg) { $relroad =$1;}
+ $relroad =~ s/\n//sg;
+
+ $skipfirst =1; #skipping the header of the table
+ while ($relroad =~ m/\<tr\>(.*?)\<\/tr(.*)/sg){
+ $myfeat=$1;
+ $relroad =$2;
+ if ($skipfirst) {$skipfirst=0;next;}
+ $package="";
+ if ($myfeat =~ m/title\=\"(.*?)\"/sg) { $package=$1; } #looking for package name
+
+ $myfeat=~ s/\<\/td\>\<td\>/\",\"/sg;
+ $myfeat=~ s/\<.*?\>//sg;
+
+ if ($myfeat =~m/[A-z]/sg ){prntfeatures($_,$package,$myfeat,outputfile,$domain);}
+
+ }
+ }
+ }
+ } else {
+
+ foreach (@releases) {
+
+ $exp="\\<h2\\>.*?\\>".$_;
+
+ if ($roadmap =~ m /($exp)/sg) {
+ print "PASS - Found entry for $_ \n";
+ $relroad =$';
+
+ if ($relroad =~ m /(.*?)\<h2/sg) { $relroad =$1;}
+ $i=0;
+ while ($relroad=~ m/\<h3\>.*\>(.*?)\<.*<\/h3/g) {
+ $package = $1;
+ $ppos[$i]= pos($relroad);
+ $pname[$i]= $package;
+ $i++;
+ }
+ for ( $i=0;$i<($#ppos); $i++){
+ $features= substr ($relroad, $ppos[$i],$ppos[$i+1]-$ppos[$i]);
+ prntfeatures($_,$pname[$i],$features,outputfile,$domain);
+ }
+ $features= substr ($relroad, $ppos[$i]);
+
+ prntfeatures($_,$pname[$i],$features,outputfile,$domain);
+ @ppos ="";
+ @pname ="";
+ undef ($features);
+ }
+ }
+
+ }
+
+
+
+ close (outputfile);
+
+
+}
+
+
+sub parse_category {
+
+ #arguments
+ ($infile)=@_;
+
+ my @mylink;
+
+ $mypage=loadfile $infile;
+ $i=0;
+ if ( $mypage =~ m/Pages in category(.*)\<\/table/sg) {
+ print "INFO - Category page found\n";
+ $mypage = $1;
+
+ while ($mypage =~ m /\<a href\=\"(\/wiki\/index\.php\/.*?)\"/g) {
+
+ $mylink[$i] = $1;
+ $i++;
+
+ }
+ print "INFO - Found $i items in the category page\n"
+ }
+ return @mylink;
+}
+
+sub bklog_domain {
+ #argument
+($mytechdomian)=@_;
+
+ $mytechdomian =~s/\)//sg;
+ $mytechdomian =~s/\(//sg;
+
+ $domaininfo=loadfile ("package_domains.csv");
+ if ($domaininfo =~ m/$mytechdomian.*?\{(.*?)\}/sgi ) {
+ return $1;
+ }
+ print "ERROR - domain not found for $mytechdomian\n";
+ return "orphan";
+
+}
+
+sub parse_bklog {
+
+ #arguments
+ ($infile,$outfile,$id)=@_;
+ $mypkg=loadfile $infile;
+ #list if the bklog has been ported to the new bugzilla based format
+ $headerformat= "wiki_format";
+
+
+ open ( outputfile, ">>".$outfile);
+ open ( soutputfile, ">>"."summary_".$outfile);
+
+ if ($mypkg =~ m/index\.php\/(.*?) HTTP/sg) {
+
+ $pagename = $1;
+
+ if ($splitbklogs) {
+ $whichtd = bklog_domain($pagename);
+ open ( tdoutputfile, ">>".$whichtd. "_".$outfile);
+ }
+
+
+
+ if (blacklist($pagename)) {
+
+ close (outputfile);
+ close (soutputfile);
+
+ if ($splitbklogs) { close (tdoutputfile);}
+ return 0;
+ }
+ print "INFO -Processing Package $pagename \n";
+ $i=0;
+ $found_counter =0;
+
+ if ($mypkg =~m/class\=\"bugzilla sortable\"/sg ) { $headerformat="autobug_format"; }
+
+ while ($mypkg =~ m/\<tr.*?\>(.*?)\<\/tr/sg) {
+ $myheader= $&;
+ if ($myheader =~ m/style=\"background-color\:/sg) {
+ next;
+ }
+ $myfeat= $1;
+ $myfeat =~ s/\<\/td\>/\t/sg;
+ $myfeat =~ s/\<.*?\>//sg;
+ $myfeat =~ s/\n//sg;
+
+ if ($myfeat =~ m/IDPStatus/sg) { #header for bugzilla mediawiki plugin
+ next;
+ }
+
+ if ($myfeat =~ m/[A-z]/sg and not $myfeat =~ m/\<\;etc/sg and
+ not $myfeat =~ m/\<\;Feature/sg and not $myfeat =~ m/Item not available/sg) {
+ print outputfile "$pagename\t$myfeat\n";
+ if ($splitbklogs) { print tdoutputfile "$pagename\t$myfeat\n";}
+
+ # print "matching $myfeat with $count_target\n" ;
+ if ($myfeat =~ m/$count_target/sg) {$found_counter++;}
+ $i++;
+ }
+
+ }
+
+ if ($count_target){
+ $mycount=$i."\t".$found_counter;
+ } else {
+ $mycount=$i;
+ }
+
+ if ($splitbklogs) {
+ print soutputfile "$id\t$pagename\t$mycount\t$headerformat\t$whichtd\thttp://developer.symbian.org/wiki/index.php/$pagename\n";
+ } else {
+ print soutputfile "$id\t$pagename\t$mycount\t$headerformat\thttp://developer.symbian.org/wiki/index.php/$pagename\n";
+ }
+
+ }
+
+ close (outputfile);
+ close (soutputfile);
+ if ($splitbklogs) { close (tdoutputfile);}
+
+}
+
+
+
+
+#help print
+sub printhelp
+{
+
+ print "\n\n version 1.1
+ \ngettd.pl -t=url -d=domain \n\nRequired parameters for Technology Roadmaps:\n\t -t url containing the technology domain roadmap\n\t -d the technology domain name
+ \n\nOptional Parmeters for Technology Roadmaps\n\t-new if the roadmap has the new wiki format
+ \n\nRequired Parameters for Package backlogs\n\t-p for package backlog analysis. just run gettd.pl -p
+ \n\nOptional Pararmeters for Package backlogs\n\t -compare [f1] [f2] compares two package summary files for changes ignores order
+ \n\t -split splits the content of the backlog output into technology domains. requires package_domains.csv file with mapping details
+ \n\t -count=regexp counts the times that a package backlog line matches the regexp, the results are output to the summary file
+ \n\nCommonOptional parameters\n\t-o filename ,the output is logged into the output.csv file by default\n\t-h for help
+ \n\t recommend to run under cygwin environment and perl version v5.10.0 \n
+ \n\t pages blacklisted for package backlogs are @blist\n";
+ exit;
+}
+
+
+
+#compare bklogs
+sub compare_bklogs {
+ #arguments
+ (@bklogs)=@_;
+
+ if (not $#bklogs == 1) { printhelp;}
+
+
+ $cmd ="cut -f 2,3 ". $bklogs[0] . " | sort -u > tmp1.txt";
+
+ system($cmd);
+
+ $cmd ="cut -f 2,3 ". $bklogs[1] . " | sort -u > tmp2.txt";
+ system($cmd);
+
+ exec ("diff tmp1.txt tmp2.txt | grep '[<|>]'");
+ system("rm temp*.txt");
+
+ exit;
+
+}
+
+
+
+
+#process command line options
+sub cmd_options
+{
+
+ my $help;
+ my @compare;
+
+
+ GetOptions('h' => \$help,'t=s'=> \$target_url, 'd=s' => \$tdomain , 'o=s' => \$csvfile,
+ 'a' => \$authon , 'p' => \$ispackage, 'compare=s{2}' =>\@compare, 'new' => \$isnewformat,
+ 'split' => \$splitbklogs, 'count=s' => \$count_target);
+
+ if (@compare) {
+ compare_bklogs @compare;
+
+ }
+ if ($count_target) {
+ print "INFO - Seaching for $count_target\n";
+ }
+
+ if ($help) {
+ printhelp;
+ }
+
+
+ if ($ispackage) {
+
+ $tdomain =" ";
+ $target_url = "http://developer.symbian.org/wiki/index.php/Category:Package_Backlog";
+
+ }
+ if ($isnewformat){
+ $newtdformat = 1;
+
+ }
+
+ if ( not $target_url) {
+
+ print "ERROR-missing arguments target url\n";
+ printhelp;
+ }
+
+
+ if (not $tdomain){
+ print "ERROR-missing arguments domain level\n";
+ printhelp;
+ }
+
+ print "\nINFO-downloading $target_url with label $tdomain\n";
+
+
+ if (not $csvfile) {
+ if (not $ispackage) {
+ $csvfile="output.csv";
+
+ } else {
+ $csvfile="output.txt";
+ system ("rm *output.txt");
+
+ }
+ }
+ print "\nINFO-output recorded in $csvfile \n";
+
+
+
+}
+#main
+$/ = " ";
+$host1 = "developer.symbian.org";
+
+cmd_options();
+
+if ($authon) {
+ #file containing login details from http cookie
+ $mycookie = loadfile("mycookie.txt");
+
+ $auth = "Cookie: " . $mycookie ;
+}
+
+
+if ($ispackage) {
+ getpage($target_url, $host1, $auth, "debug.txt");
+ @bklog = parse_category("debug.txt");
+ $j=0;
+
+ foreach (@bklog) {
+ getpage("http://".$host1.$_, $host1, $auth, "pkg".$j.".txt");
+ parse_bklog ("pkg".$j.".txt",$csvfile, $j);
+ $j++;
+
+
+
+ }
+
+} else {
+
+ #foundation releases - add as required
+ @releases=("Symbian\\^2","Symbian\\^3","Symbian\\^4");
+
+ getpage($target_url, $host1, $auth, "debug.txt");
+ td_roadmap("debug.txt" , $csvfile, $tdomain ,@releases);
}
\ No newline at end of file
Binary file scripts/python/.DS_Store has changed
Binary file scripts/python/findpackage/BeautifulSoup.pyc has changed
Binary file scripts/python/sis2rom/.DS_Store has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/python/sis2rom/sis/__init__.py Wed Jan 27 10:52:27 2010 +0000
@@ -0,0 +1,30 @@
+"""
+Copyright (c) 2006, Jari Sukanen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
Binary file scripts/python/sis2rom/sis/__init__.pyc has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/python/sis2rom/sis/sisfields.py Wed Jan 27 10:52:27 2010 +0000
@@ -0,0 +1,728 @@
+"""
+Copyright (c) 2006, Jari Sukanen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import sisreader
+import zlib
+import sys
+
+class SISFileHeader :
+ def __init__(self) :
+ self.uid1 = 0
+ self.uid2 = 0
+ self.uid3 = 0
+ self.uidChecksum = 0
+
+class SISField :
+ def __init__(self) :
+ self.type = 0
+ self.length = None
+ self.subFields = []
+
+ def readFieldLength(self, fileReader) :
+ length = fileReader.readBytesAsUint(4)
+ if length & 0x80000000 > 0 :
+ length = length << 32
+ length |= fileReader.readBytesAsUint(4)
+ return length
+
+ def findField(self, fieldType, startIndex = 0) :
+ result = None
+ index = startIndex
+
+ for field in self.subFields[startIndex:] :
+ if field.type == fieldType :
+ result = field
+ break
+ ++index
+ return (result, index)
+
+ def readableStr(self) :
+ return ""
+
+ def traverse(self, handler, depth = 0) :
+ handler.handleField(self, depth)
+ for field in self.subFields :
+ field.traverse(handler, depth + 1)
+
+class SISUnsupportedField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fileReader.readPlainBytes(self.length)
+
+class SISStringField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.data = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ buf = fileReader.readPlainBytes(self.length)
+ self.data = u""
+ while len(buf) > 0 :
+ temp = buf[:2]
+ buf = buf[2:]
+ self.data += unichr(ord(temp[0]) | ord(temp[1]) << 8)
+
+ def readableStr(self) :
+ return self.data
+
+class SISArrayField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ type = fileReader.readBytesAsInt(4)
+ l = self.length - 4
+ while l > 0 :
+ field = SISFieldTypes[type]()
+ field.type = type
+ field.initFromFile(fileReader)
+ self.subFields.append(field)
+
+ l -= field.length + 4 # field length + the length field
+ padding = fileReader.skipPadding()
+ l -= padding
+
+class SISCompressedField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.algorithm = None
+ self.uncompressedDataSize = None
+ self.data = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.algorithm = fileReader.readBytesAsUint(4)
+ self.uncompressedDataSize = fileReader.readBytesAsUint(8)
+ data = fileReader.readPlainBytes(self.length - 4 - 8)
+ if self.algorithm == 0 :
+ self.data = data
+ elif self.algorithm == 1 :
+ self.data = zlib.decompress(data)
+
+class SISVersionField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.version = (-1, -1, -1)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ major = fileReader.readBytesAsInt(4)
+ minor = fileReader.readBytesAsInt(4)
+ build = fileReader.readBytesAsInt(4)
+ self.version = (major, minor, build)
+
+ def readableStr(self) :
+ return str(self.version)
+
+class SISVersionRangeField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.fromVersion = None
+ self.toVersion = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.fromVersion = fieldParser.parseField(fileReader)
+ if self.length - fieldParser.lastReadBytes > 0 :
+ self.toVersion = fieldParser.parseField(fileReader)
+
+class SISDateField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.year = None
+ self.month = None
+ self.day = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.year = fileReader.readBytesAsUint(2)
+ self.month = fileReader.readBytesAsUint(1)
+ self.day = fileReader.readBytesAsUint(1)
+
+ def readableStr(self) :
+ return str(self.year) + "." + str(self.month) + "." + str(self.day)
+
+class SISTimeField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.hours = None
+ self.minutes = None
+ self.seconds = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.hours = fileReader.readBytesAsUint(1)
+ self.minutes = fileReader.readBytesAsUint(1)
+ self.seconds = fileReader.readBytesAsUint(1)
+
+ def readableStr(self) :
+ return str(self.hours) + ":" + str(self.minutes) + ":" + str(self.seconds)
+
+class SISDateTimeField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.date = None
+ self.time = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.date = fieldParser.parseField(fileReader)
+ self.time = fieldParser.parseField(fileReader)
+
+class SISUidField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.uid = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.uid = fileReader.readBytesAsUint(4)
+
+ def readableStr(self) :
+ return hex(self.uid)
+
+class SISLanguageField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.language = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.language = fileReader.readBytesAsUint(4)
+
+ def readableStr(self) :
+ return str(self.language)
+
+class SISContentsField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ field = fieldParser.parseField(fileReader)
+ while field :
+ if field.type == 3 : # compressed<conroller>
+ bufferReader = sisreader.SISBufferReader(field.data)
+ field = fieldParser.parseField(bufferReader)
+ self.subFields.append(field)
+ field = fieldParser.parseField(fileReader)
+
+class SISControllerField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ bufferReader = sisreader.SISBufferReader(fileReader.readPlainBytes(self.length))
+ field = fieldParser.parseField(bufferReader)
+ while field :
+ self.subFields.append(field)
+ field = fieldParser.parseField(bufferReader)
+
+class SISInfoField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.installType = None
+ self.installFlags = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # UID
+ self.subFields.append(fieldParser.parseField(fileReader)) # Vendor name unique
+ self.subFields.append(fieldParser.parseField(fileReader)) # names
+ self.subFields.append(fieldParser.parseField(fileReader)) # vendor names
+ self.subFields.append(fieldParser.parseField(fileReader)) # version
+ self.subFields.append(fieldParser.parseField(fileReader)) # creation time
+ self.installType = fileReader.readBytesAsUint(1)
+ self.installFlags = fileReader.readBytesAsUint(1)
+
+class SISSupportedLanguagesField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # languages
+
+class SISSupportedOptionsField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # options
+
+class SISPrerequisitiesField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # target devices
+ self.subFields.append(fieldParser.parseField(fileReader)) # dependencies
+
+import pdb
+
+class SISDependencyField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # UID
+ field = fieldParser.parseField(fileReader)
+ # Version range field is optional
+ if field.type == VersionRangeField :
+ self.subFields.append(field) # version range
+ self.subFields.append(fieldParser.parseField(fileReader)) # dependency names
+ else :
+ self.subFields.append(field) # dependency names
+
+class SISPropertiesField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # properties
+
+class SISPropertyField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.key = None
+ self.value = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.key = fileReader.readBytesAsInt(4)
+ self.value = fileReader.readBytesAsInt(4)
+
+# There is a type for this field, but there is no definition of the field contents
+class SISSignaturesField(SISUnsupportedField) :
+ pass
+
+class SISCertificateChainField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # certificate data
+
+class SISLogoField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # logo file
+
+class SISFileDescriptionField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.operation = None
+ self.operationOptions = None
+ self.compressedLength = None
+ self.uncompressedLength = None
+ self.fileIndex = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+
+ self.subFields.append(fieldParser.parseField(fileReader))
+ self.subFields.append(fieldParser.parseField(fileReader))
+ field = fieldParser.parseField(fileReader)
+ self.subFields.append(field)
+ if field.type == 41 : # read field was capabilities ==> there is one more field left
+ self.subFields.append(fieldParser.parseField(fileReader))
+
+ self.operation = fileReader.readBytesAsUint(4)
+ self.operationOptions = fileReader.readBytesAsUint(4)
+ self.compressedLength = fileReader.readBytesAsUint(8)
+ self.uncompressedLength = fileReader.readBytesAsUint(8)
+ self.fileIndex = fileReader.readBytesAsUint(4)
+
+ def readableStr(self) :
+ return "index: " + str(self.fileIndex)
+
+class SISHashField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.algorithm = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.algorithm = fileReader.readBytesAsUint(4)
+ self.subFields.append(fieldParser.parseField(fileReader)) # logo file
+
+class SISIfField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # expression
+ self.subFields.append(fieldParser.parseField(fileReader)) # install block
+ self.subFields.append(fieldParser.parseField(fileReader)) # else ifs
+
+class SISElseIfField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # expression
+ self.subFields.append(fieldParser.parseField(fileReader)) # install block
+
+class SISInstallBlockField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.files = None
+ self.embeddedSISFiles = None
+ self.ifBlocks = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader))
+ self.subFields.append(fieldParser.parseField(fileReader))
+ self.subFields.append(fieldParser.parseField(fileReader))
+
+class SISExpressionField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.operator = None
+ self.integerValue = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.operator = fileReader.readBytesAsUint(4)
+ self.integerValue = fileReader.readBytesAsInt(4)
+
+ if self.operator == 10 or self.operator == 13 :
+ self.subFields.append(fieldParser.parseField(fileReader))
+ if self.operator == 1 or self.operator == 2 or self.operator == 3 or self.operator == 4 or self.operator == 5 or self.operator == 6 or self.operator == 7 or self.operator == 8 or self.operator == 11 or self.operator == 12 :
+ self.subFields.append(fieldParser.parseField(fileReader))
+ if not (self.operator == 13 or self.operator == 14 or self.operator == 15 or self.operator == 16 or self.operator == 10) :
+ self.subFields.append(fieldParser.parseField(fileReader))
+
+class SISDataField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # data units
+
+class SISDataUnitField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # file data
+
+class SISFileDataField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # raw file data
+
+class SISSupportedOptionField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # names
+
+class SISControllerChecksumField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.checksum = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.checksum = fileReader.readBytesAsUint(2)
+
+class SISDataChecksumField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.checksum = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.checksum = fileReader.readBytesAsUint(2)
+
+class SISSignatureField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # signature algorithm
+ self.subFields.append(fieldParser.parseField(fileReader)) # signature data
+
+class SISBlobField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.data = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.data = fileReader.readPlainBytes(self.length)
+
+class SISSignatureAlgorithmField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # algorithm identifier
+
+class SISSignatureCertificateChainField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ fieldParser = sisreader.SISFieldParser()
+ self.subFields.append(fieldParser.parseField(fileReader)) # signatures
+ self.subFields.append(fieldParser.parseField(fileReader)) # certificate chain
+
+class SISDataIndexField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.dataIndex = None
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.dataIndex = fileReader.readBytesAsUint(4)
+
+class SISCapabilitiesField(SISField) :
+ def __init__(self) :
+ SISField.__init__(self)
+ self.capabilities = 0
+ self.readableCaps = []
+
+ def initFromFile(self, fileReader) :
+ self.length = self.readFieldLength(fileReader)
+ self.capabilities = fileReader.readBytesAsUint(self.length)
+
+ for i in range(20) :
+ if (self.capabilities >> i) & 0x01 :
+ self.readableCaps.append(CapabilityNames[i])
+
+ def readableStr(self) :
+ return " ".join(self.readableCaps)
+
+SISFieldTypes = {
+ 1 : SISStringField,
+ 2 : SISArrayField,
+ 3 : SISCompressedField,
+ 4 : SISVersionField,
+ 5 : SISVersionRangeField,
+ 6 : SISDateField,
+ 7 : SISTimeField,
+ 8 : SISDateTimeField,
+ 9 : SISUidField,
+ 10 : SISUnsupportedField,
+ 11 : SISLanguageField,
+ 12 : SISContentsField,
+ 13 : SISControllerField,
+ 14 : SISInfoField,
+ 15 : SISSupportedLanguagesField,
+ 16 : SISSupportedOptionsField,
+ 17 : SISPrerequisitiesField,
+ 18 : SISDependencyField,
+ 19 : SISPropertiesField,
+ 20 : SISPropertyField,
+ 21 : SISSignaturesField,
+ 22 : SISCertificateChainField,
+ 23 : SISLogoField,
+ 24 : SISFileDescriptionField,
+ 25 : SISHashField,
+ 26 : SISIfField,
+ 27 : SISElseIfField,
+ 28 : SISInstallBlockField,
+ 29 : SISExpressionField,
+ 30 : SISDataField,
+ 31 : SISDataUnitField,
+ 32 : SISFileDataField,
+ 33 : SISSupportedOptionField,
+ 34 : SISControllerChecksumField,
+ 35 : SISDataChecksumField,
+ 36 : SISSignatureField,
+ 37 : SISBlobField,
+ 38 : SISSignatureAlgorithmField,
+ 39 : SISSignatureCertificateChainField,
+ 40 : SISDataIndexField,
+ 41 : SISCapabilitiesField
+ }
+
+[StringField,
+ ArrayField,
+ CompressedField,
+ VersionField,
+ VersionRangeField,
+ DateField,
+ TimeField,
+ DateTimeField,
+ UidField,
+ UnusedField,
+ LanguageField,
+ ContentsField,
+ ControllerField,
+ InfoField,
+ SupportedLanguagesField,
+ SupportedOptionsField,
+ PrerequisitiesField,
+ DependencyField,
+ PropertiesField,
+ PropertyField,
+ SignaturesField,
+ CertificateChainField,
+ LogoField,
+ FileDescriptionField,
+ HashField,
+ IfField,
+ ElseIfField,
+ InstallBlockField,
+ ExpressionField,
+ DataField,
+ DataUnitField,
+ FileDataField,
+ SupportedOptionField,
+ ControllerChecksumField,
+ DataChecksumField,
+ SignatureField,
+ BlobField,
+ SignatureAlgorithmField,
+ SignatureCertificateChainField,
+ DataIndexField,
+ CapabilitiesField] = range(1, 42)
+
+FieldNames = {
+ 0 : "ROOT",
+ StringField : "StringField",
+ ArrayField : "ArrayField",
+ CompressedField : "CompressedField",
+ VersionField : "VersionField",
+ VersionRangeField : "VersionRangeField",
+ DateField : "DateField",
+ TimeField : "TimeField",
+ DateTimeField : "DateTimeField",
+ UidField : "UidField",
+ UnusedField : "UnusedField",
+ LanguageField : "LanguageField",
+ ContentsField : "ContentsField",
+ ControllerField : "ControllerField",
+ InfoField : "InfoField",
+ SupportedLanguagesField : "SupportedLanguagesField",
+ SupportedOptionsField : "SupportedOptionsField",
+ PrerequisitiesField : "PrerequisitiesField",
+ DependencyField : "DependencyField",
+ PropertiesField : "PropertiesField",
+ PropertyField : "PropertyField",
+ SignaturesField : "SignaturesField",
+ CertificateChainField : "CertificateChainField",
+ LogoField : "LogoField",
+ FileDescriptionField : "FileDescriptionField",
+ HashField : "HashField",
+ IfField : "IfField",
+ ElseIfField : "ElseIfField",
+ InstallBlockField : "InstallBlockField",
+ ExpressionField : "ExpressionField",
+ DataField : "DataField",
+ DataUnitField : "DataUnitField",
+ FileDataField : "FileDataField",
+ SupportedOptionField : "SupportedOptionField",
+ ControllerChecksumField : "ControllerChecksumField",
+ DataChecksumField : "DataChecksumField",
+ SignatureField : "SignatureField",
+ BlobField : "BlobField",
+ SignatureAlgorithmField : "SignatureAlgorithmField",
+ SignatureCertificateChainField : "SignatureCertificateChainField",
+ DataIndexField : "DataIndexField",
+ CapabilitiesField : "CapabilitiesField"
+}
+
+CapabilityNames = {
+ 0 : "TCB",
+ 1 : "CommDD",
+ 2 : "PowerMgmt",
+ 3 : "MultimediaDD",
+ 4 : "ReadDeviceData",
+ 5 : "WriteDeviceData",
+ 6 : "DRM",
+ 7 : "TrustedUI",
+ 8 : "ProtServ",
+ 9 : "DiskAdmin",
+ 10 : "NetworkControl",
+ 11 : "AllFiles",
+ 12 : "SwEvent",
+ 13 : "NetworkServices",
+ 14 : "LocalServices",
+ 15 : "ReadUserData",
+ 16 : "WriteUserData",
+ 17 : "Location",
+ 18 : "SurroundingsDD",
+ 19 : "UserEnvironment"
+ }
\ No newline at end of file
Binary file scripts/python/sis2rom/sis/sisfields.pyc has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/python/sis2rom/sis/sisinfo.py Wed Jan 27 10:52:27 2010 +0000
@@ -0,0 +1,55 @@
+"""
+Copyright (c) 2006, Jari Sukanen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import struct
+import sisfields, sisreader
+
+class SISInfo(sisfields.SISField) :
+ def __init__(self) :
+ sisfields.SISField.__init__(self)
+ self.fin = None
+ self.fileHeader = sisfields.SISFileHeader()
+
+ def parse(self, filename) :
+ fin = open(filename, 'rb')
+ fileReader = sisreader.SISFileReader(fin)
+ self.parseHeader(fileReader)
+ self.parseSISFields(fileReader)
+
+ def parseHeader(self, fileReader) :
+ self.fileHeader.uid1 = fileReader.readBytesAsUint(4)
+ self.fileHeader.uid2 = fileReader.readBytesAsUint(4)
+ self.fileHeader.uid3 = fileReader.readBytesAsUint(4)
+ self.fileHeader.uidChecksum = fileReader.readBytesAsUint(4)
+
+ def parseSISFields(self, fileReader) :
+ parser = sisreader.SISFieldParser()
+ while not fileReader.isEof() :
+ self.subFields.append(parser.parseField(fileReader))
Binary file scripts/python/sis2rom/sis/sisinfo.pyc has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/python/sis2rom/sis/sisreader.py Wed Jan 27 10:52:27 2010 +0000
@@ -0,0 +1,150 @@
+"""
+Copyright (c) 2006, Jari Sukanen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+"""
+
+
+import struct
+import sisfields
+
+class SISReader :
+ def __init__(self) :
+ pass
+
+ def readUnsignedBytes(self, numBytes) :
+ buf = self.readPlainBytes(numBytes)
+ if len(buf) < numBytes :
+ return []
+
+ format = ""
+ for i in range(numBytes) :
+ format += "B"
+ return struct.unpack(format, buf)
+
+ def readSignedBytes(self, numBytes) :
+ buf = self.readPlainBytes(numBytes)
+ if len(buf) < numBytes :
+ return []
+
+ format = ""
+ for i in range(numBytes) :
+ format += "b"
+ return struct.unpack(format, buf)
+
+ def readBytesAsUint(self, numBytes) :
+ result = 0
+ bytes = self.readUnsignedBytes(numBytes)
+ if len(bytes) == numBytes :
+ for i in range(numBytes) :
+ result |= bytes[i] << (i*8)
+
+ return result
+
+ def readBytesAsInt(self, numBytes) :
+ result = 0
+ bytes = self.readSignedBytes(numBytes)
+ if len(bytes) == numBytes :
+ for i in range(numBytes) :
+ result |= bytes[i] << (i*8)
+
+ return result
+
+ def skipPadding(self) :
+ result = 0
+ if self.bytesRead % 4 != 0 :
+ paddingLength = 4 - self.bytesRead % 4
+ self.readPlainBytes(paddingLength)
+ result = paddingLength
+
+ return result
+
+
+class SISFileReader(SISReader) :
+ def __init__(self, inStream) :
+ self.inStream = inStream
+ self.eof = False
+ self.bytesRead = 0
+
+ def readPlainBytes(self, numBytes) :
+ if self.eof :
+ return ""
+
+ if numBytes == 0 :
+ return ""
+
+ buf = ""
+ buf = self.inStream.read(numBytes)
+ if len(buf) < numBytes :
+ self.eof = True
+ return ""
+
+ self.bytesRead += numBytes
+
+ return buf
+
+ def isEof(self) :
+ return self.eof
+
+class SISBufferReader(SISReader) :
+ def __init__(self, buffer) :
+ self.buffer = buffer
+ self.bytesRead = 0
+
+ def readPlainBytes(self, numBytes) :
+ if self.isEof() :
+ return ""
+
+ if numBytes == 0 :
+ return ""
+
+ result = self.buffer[self.bytesRead:self.bytesRead+numBytes]
+
+ self.bytesRead += numBytes
+
+ return result
+
+ def isEof(self) :
+ return self.bytesRead >= len(self.buffer)
+
+class SISFieldParser :
+ def __init__(self) :
+ self.lastReadBytes = 0
+
+ def parseField(self, fileReader) :
+ """Reads the next field from the fileReader stream and returns it"""
+ field = None
+ self.lastReadBytes = 0
+ type = fileReader.readBytesAsUint(4)
+ self.lastReadBytes += 4
+ if type != 0 :
+ field = sisfields.SISFieldTypes[type]()
+ field.type = type
+ field.initFromFile(fileReader)
+ self.lastReadBytes += field.length + 4 # Field length + length field
+ self.lastReadBytes += fileReader.skipPadding()
+ return field
Binary file scripts/python/sis2rom/sis/sisreader.pyc has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/python/sis2rom/sis2rom.py Wed Jan 27 10:52:27 2010 +0000
@@ -0,0 +1,219 @@
+"""
+Copyright (c) 2006, Jari Sukanen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+"""
+from sis import sisinfo, sisfields
+import optparse
+import sys, os
+
+APP_PATH = "epoc32" + os.sep + "apps"
+IBY_PATH = "epoc32" + os.sep + "rom" + os.sep + "include"
+CRLF = '\r\n'
+
+try:
+ os.uname()
+ ZIP_CMD = 'zip -r '
+except: # no uname on windows
+ ZIP_CMD = '7z a '
+
+PyASN1Availabe = True
+
+try :
+ from pyasn1.codec.der import decoder
+ from pyasn1.type import univ, base
+except :
+ PyASN1Availabe = False
+
+def _findItem(item, itemParent, index, objectIdentifier) :
+ if isinstance(item, base.AbstractSimpleAsn1Item) :
+ if item == objectIdentifier :
+ return itemParent[index+1]
+ else :
+ for i in range(len(item)) :
+ found = _findItem(item[i], item, i, objectIdentifier)
+ if found :
+ return found
+
+def findItem(decodedCert, objectIdentifier) :
+ return _findItem(decodedCert, None, 0, objectIdentifier)
+
+
+class CertificateOrganization :
+ def __init__(self) :
+ pass
+
+ def parse(self, decodedCert) :
+ self.commonName = findItem(decodedCert, (2,5,4,3))
+ self.countryCode = findItem(decodedCert, (2,5,4,6))
+ self.locality = findItem(decodedCert, (2,5,4,7))
+ self.state = findItem(decodedCert, (2,5,4,8))
+ self.street = findItem(decodedCert, (2,5,4,9))
+ self.organization = findItem(decodedCert, (2,5,4,10))
+
+ def readableStr(self) :
+ buf = ""
+ if self.commonName :
+ buf += self.commonName.prettyPrint() + "\n"
+ if self.countryCode :
+ buf += self.countryCode.prettyPrint() + "\n"
+ if self.locality :
+ buf += self.locality.prettyPrint() + "\n"
+ if self.state :
+ buf += self.state.prettyPrint() + "\n"
+ if self.street :
+ buf += self.street.prettyPrint() + "\n"
+ if self.organization :
+ buf += self.organization.prettyPrint()
+ return buf
+
+class CertificateInfo :
+ def __init__(self) :
+ pass
+
+ def parse(self, decodedCert) :
+ self.issuer = CertificateOrganization()
+ self.issuer.parse(decodedCert[0][3])
+
+ self.signer = CertificateOrganization()
+ self.signer.parse(decodedCert[0][5])
+
+ def readableStr(self) :
+ buf = "Signer:\n " + "\n ".join(self.signer.readableStr().split('\n')) + "\n"
+ buf += "Issuer:\n " + "\n ".join(self.issuer.readableStr().split('\n')) + "\n"
+ return buf
+
+
+class Handler :
+ def __init__(self) :
+ self.files = []
+ self.fileDatas = []
+ self.signatureCertificateChains = []
+
+ def handleField(self, field, depth) :
+ if field.type == sisfields.FileDescriptionField :
+ self.files.append(field)
+ elif field.type == sisfields.FileDataField :
+ self.fileDatas.append(field)
+ elif field.type == sisfields.SignatureCertificateChainField :
+ self.signatureCertificateChains.append(field)
+
+ def print_iby_for_file(self, iby, extracted_file, install_path):
+ #binarypath="file=ABI_DIR\\BUILD_DIR\\"
+ #datapath="data=DATAZ_\\RESOURCE_FILES_DIR\\"
+ binarypath="file=\\"
+ datapath="data=\\"
+ #privatepath="data=\\epoc32\\data\\z\\"
+
+ install_path=install_path.replace('c:', 'z:')
+ #basename = filepath[filepath.rfind('\\')+1:]
+
+ if extracted_file.endswith('exe') or extracted_file.endswith('dll'):
+ iby.write( binarypath + extracted_file + '\t\t' + install_path + CRLF)
+ else:
+ iby.write( datapath + extracted_file + '\t\t' + install_path + CRLF)
+
+
+ def execute(self,outputname, iby) :
+ for f in self.files :
+ buf = f.findField(sisfields.StringField)[0].readableStr()
+# caps = f.findField(sisfields.CapabilitiesField)[0]
+# if caps :
+# buf += " [" + " ".join(f.findField(sisfields.CapabilitiesField)[0].readableCaps) + "]"
+
+ install_path=buf
+ parts = f.findField(sisfields.StringField)[0].readableStr().split("\\")
+ #for part in parts:
+ # print part
+ if len(parts[len(parts) - 1]) > 0 :
+ path = os.getcwd() + os.sep + APP_PATH
+
+ path += os.sep + os.sep.join(parts[1:-1])
+ rel_file = APP_PATH + os.sep + outputname + os.sep + os.sep.join(parts[1:])
+ rel_file = rel_file.replace('/','\\')
+ if not os.path.exists(path) :
+ os.makedirs(path)
+ extracted_file = path + os.sep + parts[len(parts) - 1]
+ newFile = file(extracted_file, "wb")
+ newFile.write(self.fileDatas[f.fileIndex].findField(sisfields.CompressedField)[0].data)
+ newFile.close()
+ self.print_iby_for_file(iby,rel_file, install_path)
+
+class ContentPrinter :
+ def __init__(self) :
+ pass
+
+ def handleField(self, field, depth) :
+ buf = ""
+ for i in range(depth) :
+ buf += " "
+ buf += sisfields.FieldNames[field.type] + " "
+ if len(field.readableStr()) > 0 :
+ buf += field.readableStr()
+ print buf
+
+import pdb
+
+if __name__ == "__main__" :
+ if len(sys.argv) == 1:
+ print "usage: %s <sisfile>" % sys.argv[0]
+ exit()
+
+ sisname = sys.argv[1]
+ sisInfo = sisinfo.SISInfo()
+ sisInfo.parse(sisname)
+
+ handler = Handler()
+ sisInfo.traverse(handler)
+
+ tmp = sisname.lower()
+
+ if tmp.find(os.sep):
+ tmp = sisname[sisname.rfind(os.sep)+1:]
+
+ if tmp.find('sisx'):
+ tmp = tmp[0:len(tmp)-4]
+ elif tmp.find('sis'):
+ tmp = tmp[0:len(tmp)-3]
+
+ iby_path = os.getcwd() + os.sep + IBY_PATH + os.sep
+ iby_file = tmp + ".iby"
+
+ if not os.path.exists(iby_path) :
+ os.makedirs(iby_path)
+
+ iby = open(iby_path + iby_file,'w')
+ print "Creating IBY file..."
+ iby.write( "#ifndef __%s_IBY__" % tmp.upper() + CRLF)
+ iby.write( "#define __%s_IBY__" % tmp.upper() + CRLF)
+ print "Extracting SIS..."
+ handler.execute(tmp, iby)
+ iby.write( "#endif" + CRLF)
+ iby.close()
+ print "Zipping..."
+ os.system(ZIP_CMD + tmp + '.zip epoc32')
+ print "All done. Remember to #include <%s> in your main IBY file" % iby_file
\ No newline at end of file