#!/usr/bin/perl
#
# Copyright (c) International Business Machines Corp., 2006
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

#
# mkpfi
#
# This perl program is assembles PFI files from a config file.
#
# Author: Oliver Lohmann (oliloh@de.ibm.com)
#
use warnings;
use strict;
use lib "/usr/lib/perl5"; # Please change this path as you need it, or
			  # make a proposal how this could be done
			  # nicer.
use Getopt::Long;
use Pod::Usage;
use Config::IniFiles;
use File::Temp;

# ----------------------------------------------------------------------------
# Versions
our $version : unique = "0.1";
our $pfi_version : unique = "0x1";

# ----------------------------------------------------------------------------
# Globals
my $verbose = 0;
my $cfg;

my %opts = ();
my %files = (config => "");
my @tmp_files;

my %tools = (ubicrc32 => "ubicrc32");

# ----------------------------------------------------------------------------
# Processing the input sections
#
# The idea is to combine each section entry with a function
# in order to allow some kind of preprocessing for the values
# before they are written into the PFI file.
# This is especially useful to be more verbose and
# user-friendly in the layout file.
#
# All key-function hashes are applied after the general
# validation of the configuration file.
# If any mandatory key is missing in a section the user
# will be informed and the PFI creation process is aborted.
#
# Default keys will be checked for their presence inside the config
# file. If they are missing, they will be generated with appr. values.

# Mandatory keys for UBI volumes.
my %ubi_keys = ("ubi_ids"       => \&check_id_list,
		"ubi_size"      => \&replace_num,
		"ubi_type"      => \&replace_type,
		"ubi_names"     => \&remove_spaces,
		"ubi_alignment" => \&replace_num);

# Mandatory keys for RAW sections.
my %raw_keys = ("raw_starts"     => \&expand_starts,
		"raw_total_size" => \&replace_num);

# Common default keys for documentation and control purposes.
my %common_keys = ("flags" => \&replace_num,
		   "label" => \&do_nothing);

# Define any defaults here. Values which maintained in this default
# region need not to be specified by the user explicitly.
my %def_ubi_keys      = ("ubi_alignment" => [\&set_default, "0x1"]);
my %def_raw_keys      = ();
my %def_common_keys   = ("flags"	 => [\&set_default, "0x0"],
			 "label"	 => [\&generate_label, ""]);

# ----------------------------------------------------------------------------
# Input keys, actually the path to the input data.

my %input_keys = ("image" => \&do_nothing);

# Placeholder keys allow the replacement via a special
# purpose function. E.g. the bootenv_file key will be used
# to generate bootenv binary data from an text file and
# replace the bootenv_file key with an image key to handle it
# in the same way in the further creation process.
my %input_placeholder_keys = ("bootenv_file" => \&create_bootenv_image);

# ----------------------------------------------------------------------------
# Helper

# @brief Get current time string.
sub get_date {
	my $tmp = scalar localtime;
	$tmp =~ s/ /_/g;
	return $tmp;
}

# @brief Print an info message to stdout.
sub INFO($) {
	my $str = shift;

	if (!$verbose) {
		return;
	}

	print STDOUT $str;
}

# @brief Print an error message to stderr.
sub ERR($) {
	my $str = shift;
	print STDERR $str;
}

# @brief Print a warning message to stderr.
sub WARN($) {
	my $str = shift;
	print STDERR $str;
}

sub parse_command_line($) {
	my $opt = shift;
	my $result = GetOptions( "help"	     => \$$opt{'help'},
				 "man"	     => \$$opt{'man'},
				 "config=s"  => \$$opt{'config'},
				 "verbose"   => \$$opt{'verbose'},
			       ) or pod2usage(2);
	pod2usage(1) if defined ($$opt{help});
	pod2usage(-verbose => 2) if defined ($$opt{man});

	$verbose = $$opt{verbose} if defined $$opt{verbose};

	if (!defined $$opt{config}) {
		ERR("[ ERROR: No config file specified. Aborting...\n");
		exit 1;
	}

}

# @brief Check if all needed tools are in PATH.
sub check_tools {
	my $err = 0;
	my $key;

	foreach $key (keys %tools) {
		if (`which $tools{$key}` eq "") {
			ERR("\n") if ($err == 0);
			ERR("! Please add the tool \'$tools{$key}\' " .
				"to your path!\n");
			$err = 1;
		}
	}
	die "[ ERROR: Did not find all needed tools!\n" if $err;
}

sub open_cfg_file($) {
	my $fname = shift;
	my $res = new Config::IniFiles( -file => $fname );

	die "[ ERROR: Cannot load your config file!\n" if (!defined $res);
	return $res;
}

sub set_default($$$$) {
	my ($cfg, $section, $parameter, $def_value) = @_;
	$cfg->newval($section, $parameter, $def_value);
	return;
}

sub generate_label($$$$) {
	my ($cfg, $section, $parameter, $def_value) = @_;
	my $new_label = $def_value . $section;
	$new_label .= "_" . get_date;
	$cfg->newval($section, $parameter, $new_label);
	return;
}

# @brief   Converts any num to a unified hex string, i.e the resulting value
#	   always starts with "0x" and is aligned to 8 hexdigits.
# @return  Returns 0 on success, otherwise an error occured.
#
sub any_num_to_hex($$) {
	my $val = shift;
	my $res = shift;

	# M(iB)
	if ($val =~ m/([0-9]+)[Mm][i]?[Bb]?/g) {
		$$res = sprintf("0x%08x", $1 * 1024 * 1024);
	}
	# k(iB)
	elsif ($val =~ m/([0-9]+)[kK][i]?[Bb]?/g) {
		$$res = sprintf("0x%08x", $1 * 1024);
	}
	# hex
	elsif ($val =~ m/0x?([0-9a-fA-F]+)/g) {
		$$res = sprintf("0x%08x", hex $1);
	}
	# decimal
	elsif ($val =~ m/^([0-9]+)$/g) {
		$$res = sprintf("0x%08x", $1);
	}
	else {
		$$res = "";
		return -1;
	}

	return 0;
}

sub remove_spaces($$$) {
	my ($cfg, $section, $parameter) = @_;
	my ($start, @starts, @new_starts);
	my $val = $cfg->val($section, $parameter);
	my $res;

	$val =~ s/ //g; # spaces
	$cfg->newval($section, $parameter, $val);
}

sub expand_starts($$$) {
	my ($cfg, $section, $parameter) = @_;
	my ($start, @starts, @new_starts);
	my $val = $cfg->val($section, $parameter);
	my $res;

	$val =~ s/ //g; # spaces
	@starts = split(/,/, $val);

	foreach $start (@starts) {
		if (any_num_to_hex($start, \$res) != 0) {
			ERR("[ ERROR: [$section]\n");
			ERR("[        Expecting a list of numeric " .
			    "values for parameter: $parameter\n");
			exit 1;
		}
		push (@new_starts, $res);
	}
	$res = join(',', @starts);

	$cfg->newval($section, $parameter, $res);
}

sub check_id_list($$$) {
	my ($cfg, $section, $parameter) = @_;
	my $val = $cfg->val($section, $parameter);
	my $res;

	if (!($val =~ m/^[0-9]+[,0-9]*/)) {
		ERR("[ ERROR: Syntax error in 'ubi_ids' in " .
		    "section '$section': $val\n");
			ERR("[ Aborting... ");
			exit 1;
	}
}

sub replace_type($$$) {
	my ($cfg, $section, $parameter) = @_;
	my $val = $cfg->val($section, $parameter);
	my $res;

	$res = lc($val);
	grep {$res eq $_} ('static', 'dynamic')
	    or die "[ ERROR: Unknown UBI Volume Type in " .
	    "section '$section': $val\n";

	$cfg->newval($section, $parameter, $res);
}


sub replace_num($$$) {
	my ($cfg, $section, $parameter) = @_;
	my $val = $cfg->val($section, $parameter);
	my $res = "";

	if (any_num_to_hex($val, \$res) != 0) {
		ERR("[ ERROR: [$section]\n");
		ERR("[        Expecting a numeric value " .
		    "for parameter: $parameter\n");
		exit 1;
	}
	$cfg->newval($section, $parameter, $res);
}

sub do_nothing($$$) {
	my ($cfg, $section, $parameter) = @_;
	return;
}

sub bootenv_sanity_check($) {
	my $env = shift;	# hash array containing bootenv
	my %pdd = ();

	defined($$env{'pdd'}) or return "'pdd' not defined";
	foreach (split /,/, $$env{'pdd'}) {
		defined($$env{$_}) or return "undefined '$_' in pdd";
		$pdd{$_} = 1;
	}

	defined $$env{'pdd_preserve'} or
		return "";
	foreach (split /,/, $$env{'pdd_preserve'}) {
		defined($pdd{$_})
			or return "pdd_preserve field '$_' not in pdd";
	}
	return "";
}

sub create_bootenv_image($$$) {
	my ($cfg, $section, $parameter) = @_;
	my $txt_fn = $cfg->val($section, "bootenv_file");
	my $in;

	my %value = ();
	my @key = ();

	open $in, "<", $txt_fn
		or die "[ ERROR: can't open bootenv file '$txt_fn'.\n";
	while (<$in>) {
		next if (/^\s*(\#.*)?$/); # Skip comments/whitespace.

		if (/^(\S+?)\+\=(.*)$/) {
			defined($value{$1}) or
				die "$txt_fn:$.: error: appending to" .
					" non-existent '$1'\n";
			$value{$1} .= $2;
		} elsif (/^(\S+?)\=(.*)$/) {
			not defined($value{$1}) or
				die "$txt_fn:$.: error: trying to" .
					" redefine '$1'\n";
			push @key, $1;
			$value{$1} = $2;
		} else {
			die "$txt_fn:$.: error: unrecognized syntax\n";
		}
	}
	close $in;

	$_ = &bootenv_sanity_check(\%value)
		and die "$txt_fn: error: $_\n";

	my $tmp_file = new File::Temp();
	push (@tmp_files, $tmp_file);

	foreach (@key) {
		print $tmp_file "$_=", $value{$_}, "\0";
	}
	close $tmp_file;

	$cfg->newval($section, "image", $tmp_file-> filename);
}

sub process_keys($$$) {
	my ($cfg, $section, $keys) = @_;
	my @parameters = $cfg->Parameters($section);
	my $i;

	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) {
		if (defined($$keys{$parameters[$i]})) {
			$$keys{$parameters[$i]}->($cfg, $section,
					$parameters[$i]);
		}
	}

}

sub is_in_keylist($$) {
	my ($key, $keys) = @_;
	my $i;

	for ($i = 0; $i < scalar(@$keys); $i++) {
		if ($$keys[$i] eq $key) {
			return 1;
		}
	}

	return 0;
}

sub check_default_keys($$$) {
	my ($cfg, $section, $keys) = @_;
	my @parameters = $cfg->Parameters($section);
	my $key;

	foreach $key (keys %$keys) {
		if (!is_in_keylist($key, \@parameters)) {
			$$keys{$key}[0]->
				($cfg, $section, $key, $$keys{$key}[1]);
		}
	}

}



sub check_keys($$$) {
	my ($cfg, $section, $keys) = @_;
	my @parameters = $cfg->Parameters($section);
	my ($i, $key, $err);

	$err = 0;
	for ($i = 0 ; $i < scalar(@$keys) ; $i++ ) {
		if (!is_in_keylist($$keys[$i], \@parameters)) {
			ERR("[ ERROR: [$section]\n") if $err == 0;
			$err = 1;
			ERR("[        Missing key '$$keys[$i]'\n");
		}
	}

	if ($err) {
		ERR("[ Aborting...\n");
		exit 1;
	}
}

sub push_pfi_data($$$$$) {
	my ($cfg, $section, $pfi_infos, $keys, $mode) = @_;
	my ($tmp, $i, $hdr);

	my %pfi_info = ();
	$pfi_info{'mode'} = $mode;
	$pfi_info{'image'} = $cfg->val($section, "image");

	# Build the PFI header
	$hdr  = sprintf("PFI!\n");
	$hdr .= sprintf("version=0x%08x\n", hex $pfi_version);
	$hdr .= sprintf("mode=$mode\n");

	# calculate the size of the binary data part
	$tmp = -s $cfg->val($section, "image");
	if (!defined $tmp) {
		ERR("[ ERROR: [$section]\n");
		ERR("[        Missing input image: "
				. $cfg->val($section, "image") . "\n");
		exit 1;
	}
	# Check for the image to fit into the given space
	my $quota;
	if ($mode eq 'raw') {
		$quota = oct $cfg->val($section, "raw_total_size");
	} elsif ($mode eq 'ubi') {
		$quota = oct $cfg->val($section, "ubi_size");
	}
	$tmp <= $quota
		or die "[ERROR: image file too big: " .
		$cfg->val($section, "image") . "\n";
	$pfi_info{'size'} = $tmp;

	$hdr .= sprintf("size=0x%08x\n", $tmp);

	my $img_file = $cfg->val($section, "image");
	my $crc32 = `$tools{'ubicrc32'} $img_file 2>&1`;
	if (any_num_to_hex($crc32, \$tmp) != 0) {
		die "[ ERROR: $tools{'ubicrc32'} returned with errors";
	}
	$hdr .= sprintf("crc=$tmp\n");


	# Process all remaining keys
	for ($i = 0; $i < scalar (@$keys); $i++) {
		if ($$keys[$i] eq "image") { # special case image input file
			if (! -e ($tmp = $cfg->val($section, "image"))) {
				ERR("[ ERROR: [$section]\n");
				ERR("[        Cannot find input file $tmp\n");
				exit 1;
			}
			next;
		}
		$hdr .= sprintf("%s=%s\n", $$keys[$i],
				$cfg->val($section, $$keys[$i]));
	}

	$hdr .= sprintf("\n"); # end marker for PFI-header

	$pfi_info{'header'} = $hdr;

	# store in the header list
	push @$pfi_infos, \%pfi_info;
}

sub process_section($$$$$$) {
	my ($cfg, $section, $pfi_infos, $custom_keys,
			$def_custom_keys, $mode) = @_;
	my @keys = (keys %common_keys, keys %$custom_keys);
	my @complete_keys = (@keys, keys %input_keys);

	# set defaults if necessary
	check_default_keys($cfg, $section, $def_custom_keys);
	check_default_keys($cfg, $section, \%def_common_keys);

	# check for placeholders...
	process_keys($cfg, $section, \%input_placeholder_keys);

	# VALIDATE layout.cfg entries
	check_keys($cfg, $section, \@complete_keys);

	# execute linked functions (if any)
	process_keys($cfg, $section, \%common_keys);
	process_keys($cfg, $section, $custom_keys);

	push_pfi_data($cfg, $section, $pfi_infos, \@keys, $mode);
}

sub get_section_info($$) {
	my ($cfg, $section) = @_;
	my @parameters = $cfg->Parameters($section);
	my ($ubi, $raw, $i, @res);

	$ubi = $raw = 0;
	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) {
		if ($parameters[$i] =~ m/ubi_/gi) {
			$ubi = 1;
			@res = (\%ubi_keys, \%def_ubi_keys, "ubi");
		}
		if ($parameters[$i] =~ m/raw_/gi) {
			$raw = 1;
			@res = (\%raw_keys, \%def_raw_keys, "raw");
		}
	}

	if (($ubi + $raw) != 1)	{ # double definition in section
		ERR("[ ERROR: Layout error in section '$section'\n");
		exit 1;
	}

	return @res;
}

sub mk_target_list($$) {
	my $val = shift;
	my $tmp = shift;
	my $complete = 0;

	if ($val =~ m/\((.*)\)/g) {
		$val = $1;
		$complete = 1;
	}
	$val =~ s/ //g; # spaces

	@$tmp = split(/,/, $val);

	return $complete;
}

sub copy_bytes($$$) {
	my ($in, $out, $to_copy) = @_;

	while ($to_copy) {
		my $buf;
		my $bufsize = 1024*1024;

		$bufsize < $to_copy or $bufsize = $to_copy;
		read($in, $buf, $bufsize) == $bufsize
			or die "[ ERROR: Image file shrunk during operation\n";
		print $out $buf;
		$to_copy -= $bufsize;
	}
}

sub write_target($$) {
	my ($pfi_infos, $target) = @_;
	my ($pfi_info);

	INFO("[ Writting target pfi file: '$target.pfi'...\n");
	if (-e "$target.pfi") {
		WARN("! Replaced old pfi...\n");
		`rm -f $target.pfi`;
	}
	open(FILE, ">", "$target.pfi")
		or die "[ ERROR: Cannot create output file: $target.pfi\n";
	binmode(FILE);

	# @FIXME sort by mode (first raw, then ubi)
	# Currently this ordering is based on a string comparism. :-)
	@$pfi_infos = sort {(lc $$a{'mode'}) cmp (lc $$b{'mode'})} @$pfi_infos;

	# Print all headers first
	foreach $pfi_info (@$pfi_infos) {
		print FILE $$pfi_info{'header'};

	}
	# Print the linked data sections
	print FILE "DATA\n";
	foreach $pfi_info (@$pfi_infos) {
		open(IMAGE, "<", $$pfi_info{'image'})
				or die "[ ERROR: Cannot open input image: " .
				"$$pfi_info{'image'}" . "\n";
		binmode(IMAGE);
		&copy_bytes(\*IMAGE, \*FILE, $$pfi_info{'size'});
		close(IMAGE) or die "[ ERROR: Cannot close input image: " .
				"$$pfi_info{'image'}" . "\n";
	}
	close(FILE) or die "[ ERROR: Cannot close output file: $target.pfi\n";
}

sub process_config($) {
	my $cfg = shift;
	my @sections = $cfg->Sections;
	my ($i, $j, $keylist, $def_keylist, $mode, $tmp,
			@tlist, $complete,@pfi_infos);

	my @parameters = $cfg->Parameters("targets") or
		die "[ ERROR: Config file has no 'targets' section!\n";

	for ($i = 0 ; $i < scalar(@parameters) ; $i++ ) {
		INFO("[ Processing target '$parameters[$i]'...\n");
		@pfi_infos = ();

		# get a list of subtargets
		$complete = mk_target_list($cfg->val("targets",
					$parameters[$i]), \@tlist);
		# build all subtargets
		for ($j = 0 ; $j < scalar(@tlist) ; $j++ ) {
			($keylist, $def_keylist, $mode)
				= get_section_info($cfg, $tlist[$j]);
			process_section($cfg, $tlist[$j],
					\@pfi_infos,
					$keylist, $def_keylist, $mode);
		}

		write_target(\@pfi_infos, $parameters[$i]);
	}

	INFO("[ Success.\n");


}

sub clear_files() {
	# @FIXME:
	# Works implicitly and Fedora seems to have removed
	# the cleanup call. Thus for now, inactive.
	# File::Temp::cleanup();
}

require 5.008_000;		# Tested with version 5.8.0.
select STDOUT; $| = 1;		# make STDOUT output unbuffered
select STDERR; $| = 1;		# make STDERR output unbuffered

parse_command_line(\%opts);
check_tools;
$cfg = open_cfg_file($opts{config});
process_config($cfg);
clear_files;

__END__


=head1 NAME

mkpfi - Using GetOpt::Long, Pod::Usage, Config::IniFiles


=head1 SYNOPSIS

mkpfi  [OPTIONS ...]


	OPTION

	[--config] [--help] [--man]


=head1 ABSTRACT

Perl script for generating pdd pfi files from given config files.

=head1 OPTIONS

=over

=item B<--help>

Print out brief help message.

=item B<--usage>

Print usage.

=item B<--config>

Config input file.

=item B<--man>

Print manual page, same as 'perldoc mkpfi'.

=item B<--verbose>

Be verbose!

=back

=head1 BUGS

Report via MTD mailing list


=head1 SEE ALSO

http://www.linux-mtd.infradead.org/


=head1 AUTHOR

Oliver Lohmann (oliloh@de.ibm.com)

=cut
