#!/usr/bin/perl -w
#
# $Id$
# Copyright B. Cornec 2005-2014
# Provided under the GPL v2
#
# Get the complete network configuration of the system
#
use strict 'vars';
use ProjectBuilder::Base;
use ProjectBuilder::Version;
use Data::Dumper;
use Getopt::Long qw(:config auto_abbrev no_ignore_case);
use English;


=pod

=head1 NAME

mr-label labelling tool

=head1 DESCRIPTION

mr-label labels VFAT devices or files representing VFAT devices

=head1 SYNOPSIS

mr-label [-v][-h][-L LABEL|-U UUID] device|file

=head1 ARGUMENTS

=over 4

=item B<device|file>

This is the VFAT device or file representing a VFAT device to modify with regards to its label

=back 

=head1 OPTIONS

=over 4

=item B<-v|--verbose>

Increase verbosity

=item B<-h|--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=item B<-L LABEL> 

This is the new LABEL to put on the VFAT filesystem

=item B<-U UUID> 

This is the new UUID to put on the VFAT filesystem

=back

=head1 WEB SITES

The main Web site of the project is available at L<http://www.mondorescue.org>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.

=head1 USER MAILING LIST

For community exchanges around MondoRescue please use the list L<http://sourceforge.net/mailarchive/forum.php?forum_name=mondo-devel>

=head1 AUTHORS

The MondoRescue team lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.

=head1 COPYRIGHT

MondoRescue is distributed under the GPL v2.0 license or later,
described in the file C<COPYING> included with the distribution.

=cut

# Global variables
my ($mrver,$mrrev) = pb_version_init();
my $appname = "mr-label";
my %opts;					# CLI Options

# Initialize the syntax string

pb_syntax_init("$appname Version $mrver-$mrrev\n");

GetOptions("help|?|h" => \$opts{'h'}, 
		"man" => \$opts{'man'},
		"verbose|v+" => \$opts{'v'},
		"label|L=s" => \$opts{'L'},
		"uuid|U=s" => \$opts{'U'},
) || pb_syntax(-1,0);

if (defined $opts{'h'}) {
	pb_syntax(0,1);
}
if (defined $opts{'man'}) {
	pb_syntax(0,2);
}
if (defined $opts{'v'}) {
	$pbdebug++;
}
pb_log_init($pbdebug, $pbLOG);
pb_temp_init($pbdebug);

my $label=$opts{'L'};
my $uuid=$opts{'U'};
die "Unable no label/uuid defined" if ((not defined $label) && (not defined $uuid));

my $inputf  = $ARGV[0];
die "$0: no input file defined" if (not defined $inputf);

my($inputfh, $buffer, $offset, $length, $hexlabel);

# Evaluate the size of the FAT with blkid -p
open(FS,"blkid -p $inputf|") || die "$0: cannot blkid -p $inputf: $!";
my $verfs = <FS>;
close(FS);
$verfs =~ s/.*VERSION="FAT([0-9][0-9]).*"/FAT$1/;
chomp($verfs);
pb_log(1,"Working on a FS ot type ***$verfs***\n");

open($inputfh,  "+< $inputf") || die "$0: cannot open $inputf for reading/writing: $!";
binmode($inputfh) || die "binmode failed: $!";

# Source https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html
if (defined $label) {
	# x first bytes are untouched
	$offset = 43 if (($verfs =~ /FAT16/) || ($verfs =~ /FAT12/));
	$offset = 71 if ($verfs =~ /FAT32/);
	$length = 11;
} elsif (defined $uuid) {
	# x first bytes are untouched
	$offset = 39 if (($verfs =~ /FAT16/) || ($verfs =~ /FAT12/));
	$offset = 67 if ($verfs =~ /FAT32/);
	$length = 4;
} else {
	die "Nothing to do no label/uuid defined";
}

if (! seek($inputfh, $offset,0)) {
	die "Unable to seek $inputf: $!";
}
# then read the following bytes
my $size = read($inputfh, $buffer, $length);
if ($size != $length) {
	die "Unable to read existing label/uuid: $!";
}

if (defined $label) {
	pb_log(1,"Previous label was ***$buffer***\n");
} elsif (defined $uuid) {
	my ($hex) = unpack( 'H*', $buffer );
	pb_log(1,"Previous hex was ***$hex***\n");
	my @loc = ($hex =~ m/../g);
	#print Dumper(@loc);
	$hex = join('',reverse(@loc));
	pb_log(1,"Previous uuid was ***$hex***\n");
} else {
	die "Nothing to do no label/uuid defined";
}
	
if (defined $label) {
	$hexlabel=sprintf("%-11s", uc($label));
	pb_log(1,"New label is ***$hexlabel***\n");
} elsif (defined $uuid) {
	# Remove separator
	$uuid =~ s/-//;
	pb_log(1,"New uuid is ***$uuid***\n");
	my @loc = ($uuid =~ m/../g);
	my $hex = join('',reverse(@loc));
	($hexlabel) = pack( 'H*', $hex );
} else {
	die "Nothing to do no label/uuid defined";
}
# Go back
seek($inputfh, $offset,0);
print $inputfh $hexlabel;
close($inputfh) || die "couldn't close $inputf: $!";
