#!/usr/bin/perl

use strict;

my $xray_dir = "/tmp/xray";
my $xray_log = "/tmp/xray/xraylog";
my ($stamp) = `date +%Y%m%d%H%M%S`;
chomp($stamp);
my $xray_basename = "recoverycd_xray_${stamp}.tgz";
my $xray_file = "/tmp/$xray_basename";

sub search_usb_disks
{
	my @disks;
	
	for(my $i=ord('a'); $i<=ord('z'); $i++) {
		my $disk = "/dev/sd".chr($i);
		open(FH, $disk) || next;
		close(FH);
		
		my ($host, $channel, $id, $lun) = split(/ +/, `/usr/local/bin/scsiGetABTL $disk`);
		if(!defined $host) {
			next;
		}
		if(system("ls /proc/scsi/usb-storage/$host > /dev/null 2>&1")) {
			next;
		}
		
		$disks[@disks] = $disk;
	}
	return \@disks;
}

sub generate_xray
{
	system("rm -rf $xray_dir");
	system("mkdir $xray_dir");
	
	# version
	system("cp /usr/local/bin/{build_number.pl,config.pl} $xray_dir 2>>$xray_log");
	# proc
	system("mkdir $xray_dir/proc 2>>$xray_log");
	system("cp -ar /proc/{bus,pci,ide,scsi,modules,iomem,ioports,partitions} $xray_dir/proc/ 2>>$xray_log");
	# net
	system("mkdir $xray_dir/net 2>>$xray_log");
	system("ifconfig -a > $xray_dir/net/ifconfig 2>>$xray_log");
	system("route > $xray_dir/net/route 2>>$xray_log");
	system("cp /etc/resolv.conf $xray_dir/net/resolv.conf 2>>$xray_log");
	# iscsi
	system("mkdir $xray_dir/iscsi 2>>$xray_log");
	system("cp /etc/{iscsi.conf,initiatorname.iscsi} $xray_dir/iscsi 2>>$xray_log");
	# ping iscsi server
	if( -x "/etc/iscsi.conf") {
		my ($line) = `grep DiscoveryAddress /etc/iscsi.conf`;
		chomp($line);
		my @words = split(/=/, $line);
		system("ping -c 1 $words[1] > $xray_dir/net/ping 2>&1");
	} else {
		system("echo \"No Server\" > $xray_dir/net/ping");
	}
	# storage
	system("mkdir $xray_dir/storage 2>>$xray_log");
	system("sfdisk -d > $xray_dir/storage/sfdisk 2>>$xray_log");
	system("fdisk -l > $xray_dir/storage/fdisk 2>>$xray_log");
	
	# log
	system("mkdir $xray_dir/log");
	system("cp /tmp/{recoverycd.log,klogd.log,probed_hardware.detail} $xray_dir/log 2>>$xray_log");
	
	# Email
	print STDOUT "Please provide e-mail address: ";
	my $email = <STDIN>;
	system("echo -n \"$email\" > $xray_dir/email");
	
	# compact to tgz
	system("/busybox/bin/tar c $xray_dir 2>>/dev/null | /busybox/bin/gzip > $xray_file 2>>/dev/null");
}
sub detect_floppy
{
	my $ret = system("/busybox/bin/dd if=/dev/fd0 of=/dev/null bs=512 count=1 >/dev/null 2>&1") >> 8;
#	my $ret = system("dd if=/dev/fd0 of=/dev/null bs=512 count=1 >/dev/null 2>&1") >> 8;
	if($ret == 0) {
		return "/dev/fd0";
	} else {
		return undef;
	}
}

sub prepare_floppy
{
	system("mkdir -p /mnt/xray");
	my $ret = system("mount /dev/fd0 /mnt/xray 1>>$xray_log 2>>$xray_log") >> 8;
	if($ret != 0) {
		print STDERR "Failed to detect floppy, please make sure you have insert a formatted floppy.\n";
		return "Failed to detect floppy, please make sure you have insert a formatted floppy.\n";
	} else {
		return undef;
	}
}

sub prepare_usb
{
	my $disk = shift;
	
	# Get the last partition
	my @output = `fdisk -l $disk`;
	my @parts = grep(/^$disk/, @output);
	my @words = split(/[ \t]+/, $parts[$#parts]);
	my $part = $words[0];
	# Try to mount the partition
	system("mkdir -p /mnt/xray");
	my $ret = system("mount -t vfat $part /mnt/xray 1>>$xray_log 2>>$xray_log") >> 8;
	if($ret != 0) {
		# Try to mount USB floppy, its node is like /dev/sda
		$ret = system("mount -t vfat $disk /mnt/xray 1>>$xray_log 2>>$xray_log") >> 8;
		if ($ret != 0) {
			print STDERR "Failed to detect USB disk, please make sure you have insert a formatted USB disk.\n";
			return "Failed to detect USB disk, please make sure you have insert a formatted USB disk.\n";
		} else {
			return undef;
		}
	} else {
		return undef;
	}
}

sub select_disk
{
_start:
	print STDOUT "******************************************************\n";
	print STDOUT "Please insert a formatted USB disk or floppy\n";
	print STDOUT "Press <Enter> to continue...\n";
	print STDOUT "******************************************************\n";
	
	getc();
	
	my $usbdisks = search_usb_disks();
	my $floppy = "/dev/fd0";
	
	if(@{$usbdisks} == 0 && !defined $floppy) {
		print STDOUT "\nNo floppy or USB disk found!!!\n";
		goto _start;
	}
	
	my @alldisks;
	
	if(defined $floppy) {
		my %disk;
		$disk{'Device'} = "/dev/fd0";
		$disk{'Name'} = "Floppy";
		$disk{'Size'} = "";
		push(@alldisks, \%disk);
	}
	
	foreach my $usbdisk (@{$usbdisks}) {
		my %disk;
		$disk{'Device'} = $usbdisk;
		$disk{'Name'} = "USB Disk";
		my ($sizeK) = `sfdisk -s $usbdisk`;
		chomp($sizeK);
		my $sizeM = int($sizeK / 1024);
		$disk{'Size'} = "$sizeM M";
		push(@alldisks, \%disk);
	}
	
	my $sel;
	while(1) {
		print STDOUT "Please select the disk to save XRAY:\n\n";
		for(my $i=0; $i<@alldisks; $i++) {
			my $index = $i+1;
			print STDOUT "$index) $alldisks[$i]->{'Name'} $alldisks[$i]->{'Size'}\n";
		}
		print STDOUT "\nEnter your selection: ";
		
		$sel = <STDIN>;
		if( $sel<1 || $sel > @alldisks) {
			print STDOUT "Illegal selection!\n";
			next;
		}
		last;
	}
	
	my $selected_disk = $alldisks[$sel-1]->{'Device'};
	return $selected_disk;
}

sub copy_xray
{
	my $selected_disk = select_disk();
	
	my $ret;
	if($selected_disk eq "/dev/fd0") {
		$ret = prepare_floppy();
		if($ret) {
			return $ret;
		}
	}
	else {
		$ret = prepare_usb($selected_disk);
		if($ret) {
			return $ret;
		}
	}
	
	$ret = system("cp $xray_file /mnt/xray") >> 8;
	if($ret != 0) {
		system("umount /mnt/xray");
		return $ret;
	}
	$ret = system("umount /mnt/xray") >> 8;
	if($ret != 0) {
		return $ret;
	}
}

####################################################################


generate_xray();
my $ret = copy_xray();

if($ret) {
	print STDOUT "\n************************************************\n";
	print STDOUT "Failed to save XRAY, please try again!\n";
	print STDOUT "************************************************\n";
	$ret = 1;
} else {
	print STDOUT "\n************************************************\n";
	print STDOUT "Successfully saved XRAY file to disk!\n";
	print STDOUT "The file name is '$xray_basename'.\n";
	print STDOUT "************************************************\n";
	$ret = 0;
}

print STDOUT "Press Alt+F1 to return to Recovery CD\n";

exit 0;
