#!/public/bin/suidperl
#
# $Id: moin,v 1.5 2000/02/27 22:35:46 heyder Exp $
#
# MO in
# Suid-perl script so normal users can mount MOs more easy
#
# (c) 1999,2000 by Frank Heyder
#


my $MO         = "/dev/sda";
my $MOUNTPOINT = "/mo";
my $MOUNTTAB   = "/proc/mounts";
my $PARTNR     = 1;
my $ID;
my $DEV;
my $TYPE;
my $TUNE;
my $olduid;
my $status;
my $checkfs=1;
my $readonly=0;
my $option;
my $mountline;
my @mounted;

sub get_id
{
  (local $dev, local $nr) = @_;
  
  open(IN, "sfdisk -d " . $dev . " 2>/dev/null |");

  while ($line=<IN>)
  {
    if ($line =~ "/[^ 0-9]*([0-9]*).*Id=(..).*")
    {
      if ($1 == $nr)
      {
        close (IN);
        return hex $2;
      }
    }
  }
  close (IN);
  return -1;
}

$ENV{"PATH"} = "/sbin:/bin:/usr/bin:/usr/sbin:/public/bin:/public/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
$olduid = $<;
$< = $>;

foreach $option (@ARGV) {
  if ($option eq "-r") {
    $readonly=1;
  } elsif ($option eq "-n") {
    $checkfs=0;
  } else {
    print STDERR "usage: moin [-r] [-n]\nmoin (MO-in) mounts a MO (or other removable media) which can be vfat/ext2\nfilesystem on a partitioned/non partitioned media\nOptions:\n  -r  mount MO read-only\n  -n  don't check ext2 filesystems before mounting\n";
    exit (1);
  }
}

# check if allready mounted
open (IN, $MOUNTTAB);
while ($mountline=<IN>)
{
  @mounted = split (" \t\n", $mountline);
  if ($mounted[1] eq $MOUNTPOINT) {
    close (IN);
    print STDERR $MOUNTPOINT . " allready mounted\n";
    exit (2);
  }
}

# get partion ID
$ID = &get_id($MO, $PARTNR);

SWITCH: {
  if ($ID == 131) {
    # 131 = 0x83 = Linux Native -> ext2 ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "ext2";
    last SWITCH;
  }
  if ($ID == 1) {
    # 1 = 0x01 = DOS 12-bit FAT -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  if ($ID == 4) {
    # 4 = 0x04 = DOS 16-bit FAT <32M -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  if ($ID == 6) {
    # 6 = 0x06 = DOS 16-bit FAT >=32M -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  if ($ID == 11) {
    # 11 = 0x0b = Win95 FAT32 -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  if ($ID == 12) {
    # 12 = 0x0c = Win95 FAT32 (LBA) -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  if ($ID == 14) {
    # 14 = 0x0e = Win95 FAT16 (LBA) -> vfat ;-)
    $DEV = $MO . $PARTNR;
    $TYPE = "vfat";
    last SWITCH;
  }
  # nicht partitioniert
  $DEV = $MO;
  $TYPE = "ext2";

  $TUNE = "1" . `tune2fs -l $MO &>/dev/null || echo 1`;
  if ($TUNE == 11) {
    $TYPE = "vfat";
  }
}

if ($TYPE eq "vfat") {
  if ($readonly == 1) {
    print "Mounting " . $DEV . " as vfat read-only to " . $MOUNTPOINT . "\n";
    system("mount", "-t", $TYPE, "-o", "ro,umask=0077,uid=$olduid", $DEV, $MOUNTPOINT);
  } else {
    print "Mounting " . $DEV . " as vfat to " . $MOUNTPOINT . "\n";
    system("mount", "-t", $TYPE, "-o", "umask=0077,uid=$olduid", $DEV, $MOUNTPOINT);
  }
} else {
  if ($checkfs == 1) {
    $status=system ("e2fsck", "-p", $DEV);
  } else {
    $status=0;
  }
  if (($status & 6) == 6) {
    print STDERR "MO not mounted due to Filesystem error\n  Check filesystem manually or bypass filesystemcheck via the -n option (not recomended)\n";
  } else {
    if ($readonly == 1) {
      print "Mounting " . $DEV . " as ext2 read-only to " . $MOUNTPOINT . "\n";
      system ("mount", "-t", $TYPE, "-o", "ro,nosuid,nodev", $DEV, $MOUNTPOINT);
    } else {
      print "Mounting " . $DEV . " as ext2 to " . $MOUNTPOINT . "\n";
      system ("mount", "-t", $TYPE, "-o", "nosuid,nodev", $DEV, $MOUNTPOINT);
    }
  }
}


