#!/usr/bin/perl -w
# $Id: checkhotmounts,v 1.1.1.1 2004/03/10 15:41:50 adrian Exp $
@files= </var/lib/hardware/unique-keys/*>; chomp(@files);

# Read all unique hardware files...
%all=();
foreach $uniqfile (@files) {
	open(UNIQFILE,$uniqfile) || next;
	%this=();
	while (<UNIQFILE>) {
		chomp;
		if (/^\[(.*)\]/) { $section = $1; next; }
		next if (/^$/);
		next unless (/^([^=]*)=(.*)/);
		$this{$section.".".$1} = $2;
	}
	close(UNIQFILE);
	%{$all{$uniqfile}} = %this;
}

# Now evaluate them for USB Storage Devices.
%hotmounts=();
foreach $uniq (keys %all) {
	%this = %{$all{$uniq}};
	# Detect that it is a USB device, by checking for USBGUID.
	next unless (defined($this{"Hardware.USBGUID"}));
	# Only available devices.
	next unless ($this{"Status.Available"} eq 'yes');
	# Only support USB cdroms, floppies, disks (or whatever appears to 
	# be one).
	$hwclass = $this{"General.HWClass"};
	next unless (	($hwclass eq "cdrom") ||
			($hwclass eq "floppy") ||
			($hwclass eq "disk")
	);

	# Assume floppies, except ZIPs, do not have partition tables.
	if ($this{"General.Model"} =~ /ZIP/) {
		$hwclass = "zip";
	}

	# We need a UNIX Device.
	next unless (defined($this{"Hardware.UnixDevice"}));

	$unixdev = $this{"Hardware.UnixDevice"};
	$bn = $unixdev; $bn =~ s/.*\///;
	# print STDERR "$uniq - $bn ($hwclass)\n";
	$hotmounts{$bn} = $hwclass;
	$uniqnames{$bn} = $uniq;
}

# Even if we have 0 Unix Devices, we might need to delete the old entries...

%founduniq = (); # remember all uniq ids we already found.

# Remove all old HOTPLUG mounts.
open(FSTABOLD,"/etc/fstab")||die;
open(FSTABNEW,">/etc/fstab.new")||die;
while (<FSTABOLD>) {
	chomp;
	if (/^(\S*)\s.*#HOTPLUG (\S*)/) {
		$bn = $1; $uniq = $2;
		$bn =~ s/.*\///;
		$founduniq{$uniq} = $bn;
		$xline{$uniq} = $_;
		# print STDERR "$uniq - $bn\n";
		next;
	}
	print FSTABNEW "$_\n";
}
close(FSTABOLD);

$redo = 0; # This is a marker if we need to touch the /etc/fstab file.

foreach (%founduniq) {
	$bn = $_; $bn =~ s/.*\///;
	if (!$uniqnames{$bn}) {
		$redo = 1;
		last;
	}
}

foreach $bn (keys %hotmounts) {
	$hwclass = $hotmounts{$bn};
	$un = $uniqnames{$bn}; $un =~ s/.*\///;

	# print STDERR "$founduniq{$un}, $bn\n";

	# If it is the same unique id and the same device, we skip the
	# expensive checks.
	if (defined($founduniq{$un}) && ($founduniq{$un} =~ /^$bn/)) {
		print FSTABNEW "$xline{$un}\n";
		next;
	}

	# We need to redo them (and create a new fstab)
	$redo = 1;
	if (($hwclass eq "disk") || ($hwclass eq "zip")) {
		# This is the worst check. Dunno if we can do it better.
		open(SFDISK,"LANG=C sfdisk -d /dev/$bn 2>&1|");
			@sfdisk = <SFDISK>;
		close(SFDISK);
		chomp @sfdisk;

		if (grep(/No medium found/,@sfdisk)) {
			# Bad. We can't easily and consistently handle this.
			# Fix it in 8.1.
			if ($hwclass eq "zip") {
				mkdir("/media/${bn}4");
				print FSTABNEW "/dev/${bn}4 /media/${bn}4 auto noauto,user,exec 0 0 #HOTPLUG $un\n";
			}
			next;
		} else {
			@sfdisk = @sfdisk[3..$#sfdisk];
			foreach (@sfdisk) {
				# /dev/sdc1 : start=       63, size=  699489, Id= 6, bootable
				next unless (/(\S*)\s*:.* size=\s*(\d*),\s*Id=\s*(\S*)/);
				$devname=$1;$size=$2;$id=$3;
				next if (($id eq '0') || ($size == 0));
				# print STDERR "$devname\n";
				$bn = $devname; $bn =~ s/.*\///;
				mkdir("/media/$bn");
				print FSTABNEW "/dev/$bn /media/$bn auto noauto,user,exec 0 0 #HOTPLUG $un\n";
			}
		}
	} else {
		mkdir("/media/$bn");
		if ($hwclass eq "cdrom") {
			print FSTABNEW "/dev/$bn /media/$bn auto ro,noauto,user,exec 0 0 #HOTPLUG $un\n";
		} else {
			print FSTABNEW "/dev/$bn /media/$bn auto noauto,user,exec 0 0 #HOTPLUG $un\n";
		}
	}
}
close(FSTABNEW);
if ($redo) {
	rename("/etc/fstab.new","/etc/fstab");
} else {
	unlink("/etc/fstab.new");
}
exit 0;
