/* pcpart.c - manipulate fdisk partitions */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2009  Free Software Foundation, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/msdos_partition.h>
#include <grub/device.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/parttool.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv2+");

static int activate_table_handle = -1;
static int type_table_handle = -1;

static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
{
  {"boot", N_("Make partition active"), GRUB_PARTTOOL_ARG_BOOL},
  {0, 0, 0}
};

static grub_err_t grub_pcpart_boot (const grub_device_t dev,
				    const struct grub_parttool_args *args)
{
  int i, index;
  grub_partition_t part;
  struct grub_msdos_partition_mbr mbr;

  if (dev->disk->partition->offset)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("not a primary partition"));

  index = dev->disk->partition->index;
  part = dev->disk->partition;
  dev->disk->partition = part->parent;

  /* Read the MBR.  */
  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
    {
      dev->disk->partition = part;
      return grub_errno;
    }

  if (args[0].set && args[0].bool)
    {
      for (i = 0; i < 4; i++)
	mbr.entries[i].flag = 0x0;
      mbr.entries[index].flag = 0x80;
      grub_printf_ (N_("Partition %d is active now. \n"), index);
    }
  else
    {
      mbr.entries[index].flag = 0x0;
      grub_printf (N_("Cleared active flag on %d. \n"), index);
    }

   /* Write the MBR.  */
  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr);

  dev->disk->partition = part;

  return GRUB_ERR_NONE;
}

static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
{
  {"type", N_("Change partition type"), GRUB_PARTTOOL_ARG_VAL},
  {"hidden", N_("Set `hidden' flag in partition type"), GRUB_PARTTOOL_ARG_BOOL},
  {0, 0, 0}
};

static grub_err_t grub_pcpart_type (const grub_device_t dev,
				    const struct grub_parttool_args *args)
{
  int index;
  grub_uint8_t type;
  grub_partition_t part;
  struct grub_msdos_partition_mbr mbr;

  index = dev->disk->partition->index;
  part = dev->disk->partition;
  dev->disk->partition = part->parent;

  /* Read the parttable.  */
  if (grub_disk_read (dev->disk, part->offset, 0,
		      sizeof (mbr), &mbr))
    {
      dev->disk->partition = part;
      return grub_errno;
    }

  if (args[0].set)
    type = grub_strtoul (args[0].str, 0, 0);
  else
    type = mbr.entries[index].type;

  if (args[1].set)
    {
      if (args[1].bool)
	type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
      else
	type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
    }

  if (grub_msdos_partition_is_empty (type)
      || grub_msdos_partition_is_extended (type))
    {
      dev->disk->partition = part;
      return grub_error (GRUB_ERR_BAD_ARGUMENT,
			 N_("the partition type 0x%x isn't "
			    "valid"));
    }

  mbr.entries[index].type = type;
  /* TRANSLATORS: In this case we're actually writing to the disk and actively
     modifying partition type rather than just defining it.  */
  grub_printf_ (N_("Setting partition type to 0x%x\n"), type);

   /* Write the parttable.  */
  grub_disk_write (dev->disk, part->offset, 0,
		   sizeof (mbr), &mbr);

  dev->disk->partition = part;

  return GRUB_ERR_NONE;
}

GRUB_MOD_INIT (msdospart)
{
  activate_table_handle = grub_parttool_register ("msdos",
						  grub_pcpart_boot,
						  grub_pcpart_bootargs);
  type_table_handle = grub_parttool_register ("msdos",
					      grub_pcpart_type,
					      grub_pcpart_typeargs);

}
GRUB_MOD_FINI(msdospart)
{
  grub_parttool_unregister (activate_table_handle);
  grub_parttool_unregister (type_table_handle);
}
