#!/usr/bin/env perl
#-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-

# Detect, list and manipulate local media devices.
#
# Copyright (C) 2000-2001 Ximian, Inc.
#
# Authors: Hans Petter Jansson <hpj@ximian.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.


$SCRIPTSDIR = "/usr/share/setup-tool-backends/scripts";
if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
{
    $SCRIPTSDIR = ".";
    $DOTIN = ".in";
}

require "$SCRIPTSDIR/xml.pl$DOTIN";
require "$SCRIPTSDIR/parse.pl$DOTIN";


# gst_media_get_ide_device_from_proc
#
# Read IDE device specs for a single device from constructed /proc subdir and
# a couple of other places.

sub gst_media_get_ide_device_from_proc
{
  my ($path) = "/proc/ide/$_[0]/$_[1]";
  my (%device);

  %device->{"device"}   = $_[1];
  %device->{"type"}     = "ide";
  %device->{"media"}    = &gst_parse_line_first ("$path/media");
  %device->{"model"}    = &gst_parse_line_first ("$path/model");
  %device->{"cache"}    = &gst_parse_line_first ("$path/cache");
  %device->{"capacity"} = &gst_parse_line_first ("$path/capacity");
  %device->{"driver"}   = (split ' ', &gst_parse_line_first ("$path/driver")) [0];

  # TODO: We need a detailed list of media types that can occur, and what
  # special handling they need. Currently recognized are: disk, cdrom.
  #
  # Currently, everything that's not a disk is removable.

  if (%device->{"media"} eq "disk")
  {
    %device->{"is_removable"} = 0;

    # Disk devices can't be mounted and don't have file systems. Their
    # partitions can and do, however.

    # TODO: Partition information gathered in a sub-hash.
  }
  else  # (%device->{"media"} eq "cdrom")
  {
    %device->{"is_removable"} = 1;

    %device->{"point_listed"} = &gst_parse_split_first_str ("/etc/fstab", "/dev/$_[1]", "[ \t]+");
    %device->{"point_actual"} = &gst_parse_split_first_str ("/etc/mtab", "/dev/$_[1]", "[ \t]+");
    %device->{"fs_listed"}    = (&gst_parse_split_all ("/etc/fstab", "/dev/$_[1]", "[ \t]+")) -> [1];
    %device->{"fs_actual"}    = (&gst_parse_split_all ("/etc/mtab", "/dev/$_[1]", "[ \t]+")) -> [1];

    if (%device->{"point_actual"})
    {
      %device->{"is_mounted"} = 1;
    }
    else
    {
      %device->{"is_mounted"} = 0;
    }
  }

  return %device;
}


# gst_media_get_list_from_proc
#
# Scan /proc files for media devices, and return a list of hashes.

sub gst_media_get_list_from_proc
{
  local (*PROC_IDE_DIR, *PROC_IDE_CHANNEL_DIR);
  my (@devices);

  if (!(stat ("/proc"))) { return undef; }

  # IDE devices.

  if (!(opendir (PROC_IDE_DIR, "/proc/ide"))) { return undef; }

  foreach $ide_entry (readdir (PROC_IDE_DIR))
  {
    if ($ide_entry =~ /ide[0-9]/)
    {
      if (!(opendir (PROC_IDE_CHANNEL_DIR, "/proc/ide/$ide_entry"))) { next; }

      foreach $ide_channel_entry (readdir (PROC_IDE_CHANNEL_DIR))
      {
        # NOTE: This is just checking if the entry is a directory. I have a
        # feeling it's more portable than stat().

        if ($ide_channel_entry eq "." || $ide_channel_entry eq ".." ||
            !(opendir (PROC_IDE_DEVICE, "/proc/ide/$ide_entry/$ide_channel_entry")))
        {
          next;
        }

        closedir (PROC_IDE_DEVICE);

        my %device = &gst_media_get_ide_device_from_proc ($ide_entry, $ide_channel_entry);
        if (%device)
        {
          push @devices, \%device;
        }
      }
    }
  }

  return @devices;
}


# gst_media_get_list
#
# Return a list of hashes describing the media devices present
# on this machine.

sub gst_media_get_list
{
  my @devices;

  @devices = &gst_media_get_list_from_proc();
  return @devices;
}


# gst_media_xml_print
#
# Given a media hash-list, prints the media inside a <media> tag
# pair, using current indent levels.

sub gst_media_xml_print
{
  my @devices = @_;

  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<media>\n");
  &gst_xml_enter ();

  for $dev (@devices)
  {
    &gst_xml_print_vspace ();
    &gst_xml_print_line ("<device>\n");
    &gst_xml_enter ();
    &gst_xml_print_line ("<name>" . $dev->{"device"} . "</name>\n"); 
    &gst_xml_print_line ("<type>" . $dev->{"media"} . "</type>\n"); 
    &gst_xml_print_line ("<interface>" . $dev->{"type"} . "</interface>\n"); 
    &gst_xml_print_line ("<driver>" . $dev->{"driver"} . "</driver>\n"); 
    &gst_xml_print_line ("<model>" . $dev->{"model"} . "</model>\n");

    if ($dev->{"media"} ne "disk")
    {
      &gst_xml_print_vspace ();
      if ($dev->{"point_listed"})
      {
        &gst_xml_print_line ("<point_listed>" . $dev->{"point_listed"} . "</point_listed>\n");
      }

      gst_xml_print_state_tag ("mounted", $dev->{"is_mounted"});
    }

    &gst_xml_leave ();
    &gst_xml_print_line ("</device>\n");
    &gst_xml_print_vspace ();
  }

  &gst_xml_leave ();
  &gst_xml_print_line ("</media>\n");
  &gst_xml_print_vspace ();
}


# gst_media_xml_parse
#
#

sub gst_media_xml_parse
{
}
