From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LeyRF-0007EB-GI for mharc-grub-devel@gnu.org; Wed, 04 Mar 2009 16:15:37 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LeyRC-0007An-Mi for grub-devel@gnu.org; Wed, 04 Mar 2009 16:15:34 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LeyRB-0007AB-ST for grub-devel@gnu.org; Wed, 04 Mar 2009 16:15:34 -0500 Received: from [199.232.76.173] (port=58362 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LeyRB-0007A2-O7 for grub-devel@gnu.org; Wed, 04 Mar 2009 16:15:33 -0500 Received: from fg-out-1718.google.com ([72.14.220.157]:18565) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LeyRB-0007HH-1d for grub-devel@gnu.org; Wed, 04 Mar 2009 16:15:33 -0500 Received: by fg-out-1718.google.com with SMTP id l27so289512fgb.30 for ; Wed, 04 Mar 2009 13:15:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type; bh=UXQw2w8OCiQdOzQas6I/T9hxd4edaMVf4FqO8YOWgEQ=; b=DTm3R2cxVX1tYj5OykDHJa6UmmCiyRAVbJBYcWSs6he3Uw/eQRCia1cRTfT8HJA4Um wQkmzfOUMzJK9BFT7fGW9VdQPJ8nloa7ptac1gnV24ZPYqPZxHAb/UYHyOFQPWO/AFhz do+6WznmTqqgsTkqXK1fQFqg3JEaCrhB2R/6E= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type; b=pcfetorHVbJT4b39PTAEn6tR25GJOXo9NM0am7vOJyx/sVzA3p0x7X0VkBz69eCR08 TeFzuXvtW5vjf2XAxRRUJpiLAaS3x0vI5Fu2+mg/yNDfRGy7FXD4IbSUICqVECpe/aGR SMbJfgkq3e1jVsXeiOquY3/mkqsN06aqn9HAI= Received: by 10.86.71.1 with SMTP id t1mr476996fga.18.1236201331093; Wed, 04 Mar 2009 13:15:31 -0800 (PST) Received: from ?192.168.1.2? (31-206.0-85.cust.bluewin.ch [85.0.206.31]) by mx.google.com with ESMTPS id d6sm2296417fga.12.2009.03.04.13.15.30 (version=SSLv3 cipher=RC4-MD5); Wed, 04 Mar 2009 13:15:30 -0800 (PST) Message-ID: <49AEEF72.5050000@gmail.com> Date: Wed, 04 Mar 2009 22:15:30 +0100 From: phcoder User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------050607010208010804020902" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] parttool X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Mar 2009 21:15:34 -0000 This is a multi-part message in MIME format. --------------050607010208010804020902 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello here is the implementation of parttool with the syntax I proposed earlier and equivalent of parttype, makeactive and hide/unhide -- Regards Vladimir 'phcoder' Serbinenko --------------050607010208010804020902 Content-Type: text/x-patch; name="parttool.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="parttool.diff" Index: conf/common.rmk =================================================================== --- conf/common.rmk (revision 2017) +++ conf/common.rmk (working copy) @@ -334,7 +340,7 @@ cmp.mod cat.mod help.mod search.mod \ loopback.mod fs_uuid.mod configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod \ - read.mod sleep.mod loadenv.mod crc.mod + read.mod sleep.mod loadenv.mod crc.mod parttool.mod pcpart.mod # For hello.mod. hello_mod_SOURCES = hello/hello.c @@ -346,6 +352,16 @@ boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For parttool.mod. +parttool_mod_SOURCES = commands/parttool.c +parttool_mod_CFLAGS = $(COMMON_CFLAGS) +parttool_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pcpart.mod. +pcpart_mod_SOURCES = parttool/pcpart.c +pcpart_mod_CFLAGS = $(COMMON_CFLAGS) +pcpart_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For handler.mod. handler_mod_SOURCES = commands/handler.c handler_mod_CFLAGS = $(COMMON_CFLAGS) Index: conf/i386-coreboot.rmk =================================================================== --- conf/i386-coreboot.rmk (revision 2017) +++ conf/i386-coreboot.rmk (working copy) @@ -87,6 +89,7 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/i386-efi.rmk =================================================================== --- conf/i386-efi.rmk (revision 2017) +++ conf/i386-efi.rmk (working copy) @@ -65,6 +66,7 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/i386-ieee1275.rmk =================================================================== --- conf/i386-ieee1275.rmk (revision 2017) +++ conf/i386-ieee1275.rmk (working copy) @@ -87,6 +89,7 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/i386-pc.rmk =================================================================== --- conf/i386-pc.rmk (revision 2017) +++ conf/i386-pc.rmk (working copy) @@ -146,3 +147,4 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/powerpc-ieee1275.rmk =================================================================== --- conf/powerpc-ieee1275.rmk (revision 2017) +++ conf/powerpc-ieee1275.rmk (working copy) @@ -70,6 +70,7 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_script.tab.c grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/sparc64-ieee1275.rmk =================================================================== --- conf/sparc64-ieee1275.rmk (revision 2017) +++ conf/sparc64-ieee1275.rmk (working copy) @@ -66,6 +67,7 @@ # partmap/acorn.c \ # util/console.c util/grub-emu.c util/misc.c \ # util/hostdisk.c util/getroot.c \ +# commands/parttool.c parttool/pcpart.c \ # util/sparc64/ieee1275/misc.c grub_emu_LDFLAGS = $(LIBCURSES) Index: conf/x86_64-efi.rmk =================================================================== --- conf/x86_64-efi.rmk (revision 2017) +++ conf/x86_64-efi.rmk (working copy) @@ -67,6 +68,7 @@ \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/pcpart.c \ grub_emu_init.c grub_emu_LDFLAGS = $(LIBCURSES) Index: commands/parttool.c =================================================================== --- commands/parttool.c (revision 0) +++ commands/parttool.c (revision 0) @@ -0,0 +1,248 @@ +/* parttool.c - common dispatcher and parser for partition operations */ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_parttool *parts = 0; +static int curhandle = 0; +static grub_dl_t mymod; + +int +grub_parttool_register(const char *part_name, + const grub_parttool_function_t func, + const struct grub_parttool_argdesc *args) +{ + struct grub_parttool *cur; + int nargs = 0; + struct grub_parttool_argdesc *curarg; + +#ifndef GRUB_UTIL + if (!parts) + grub_dl_ref (mymod); +#endif + + cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool)); + cur->next = parts; + cur->name = grub_strdup (part_name); + cur->handle = curhandle++; + for (curarg = args; curarg->name != 0; curarg++) + nargs++; + cur->nargs = nargs; + cur->args = (struct grub_parttool_argdesc *) + grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); + grub_memcpy (cur->args, args, + (nargs + 1) * sizeof (struct grub_parttool_argdesc)); + + cur->func = func; + parts = cur; + return cur->handle; +} + +void +grub_parttool_unregister (int handle) +{ + struct grub_parttool *prev = 0, *cur; + for (cur = parts; cur; prev=cur, cur = cur->next) + if (cur->handle == handle) + { + grub_free (cur->args); + grub_free (cur->name); + if (prev) + prev->next = cur->next; + else + parts = cur->next; + grub_free (cur); + } +#ifndef GRUB_UTIL + if (!parts) + grub_dl_unref (mymod); +#endif +} + +static grub_err_t +grub_cmd_parttool (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_device_t dev; + struct grub_parttool *cur, *ptool; + int *parsed; + int i, j; + grub_err_t err = GRUB_ERR_NONE; + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments"); + + dev = grub_device_open (args[0]); + + if (!dev) + return grub_errno; + + if (!dev->disk) + { + grub_device_close (dev); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk"); + } + + if (!dev->disk->partition) + { + grub_device_close (dev); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition"); + } + + parsed = (int *)grub_malloc (argc * sizeof (int)); + grub_memset (parsed, 0, argc * sizeof (int)); + + for (i = 1; i < argc; i++) + if (!grub_strcmp (args[i], "help")) + { + int found = 0; + for (cur = parts; cur; cur = cur->next) + if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name)) + { + struct grub_parttool_argdesc *curarg; + found = 1; + for (curarg = cur->args; curarg->name; curarg++) + { + int spacing = 20; + + spacing -= grub_strlen (curarg->name); + grub_printf ("%s", curarg->name); + + switch (curarg->type) + { + case GRUB_PARTTOOL_ARG_BOOL: + grub_printf ("+/-"); + spacing-=3; + break; + + case GRUB_PARTTOOL_ARG_VAL: + grub_printf ("=VAL"); + spacing-=4; + break; + + case GRUB_PARTTOOL_ARG_END: + break; + } + while (spacing-- > 0) + grub_printf (" "); + grub_printf ("%s\n", curarg->desc); + } + } + if (!found) + grub_printf ("Sorry no parttool is available for %s\n", + dev->disk->partition->partmap->name); + return GRUB_ERR_NONE; + } + + for (i = 1; i < argc; i++) + if (!parsed[i]) + { + struct grub_parttool_argdesc *curarg; + struct grub_parttool_args *pargs; + for (cur = parts; cur; cur = cur->next) + if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name)) + { + for (curarg = cur->args; curarg->name; curarg++) + if (!grub_strncmp (curarg->name, args[i], + grub_strlen (curarg->name)) + && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL + && (args[i][grub_strlen (curarg->name)] == '+' + || args[i][grub_strlen (curarg->name)] == '-')) + || (curarg->type==GRUB_PARTTOOL_ARG_VAL + && args[i][grub_strlen (curarg->name)] == '='))) + + break; + if (curarg) + break; + } + if (!cur) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s", + args[i]); + ptool = cur; + pargs = (struct grub_parttool_args *) + grub_malloc (ptool->nargs * sizeof (struct grub_parttool_args)); + grub_memset (pargs, 0, + ptool->nargs * sizeof (struct grub_parttool_args)); + for (j = i; j < argc; j++) + if (!parsed[j]) + { + for (curarg = ptool->args; curarg->name; curarg++) + if (!grub_strncmp (curarg->name, args[i], + grub_strlen (curarg->name)) + && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL + && (args[j][grub_strlen (curarg->name)] == '+' + || args[j][grub_strlen (curarg->name)] == '-')) + || (curarg->type == GRUB_PARTTOOL_ARG_VAL + && args[j][grub_strlen (curarg->name)] == '='))) + { + parsed[j] = 1; + pargs[curarg - ptool->args].set = 1; + switch (curarg->type) + { + case GRUB_PARTTOOL_ARG_BOOL: + pargs[curarg - ptool->args].bool + = (args[j][grub_strlen (curarg->name)] != '-'); + break; + + case GRUB_PARTTOOL_ARG_VAL: + pargs[curarg - ptool->args].str + = (args[j]+grub_strlen (curarg->name)+ 1); + break; + + case GRUB_PARTTOOL_ARG_END: + break; + } + } + } + + err = ptool->func (dev, pargs); + grub_free (pargs); + if (err) + break; + } + + grub_device_close (dev); + return err; +} + +GRUB_MOD_INIT(parttool) +{ + (void)mod; /* To stop warning. */ + mymod = mod; + grub_register_command ("parttool", grub_cmd_parttool, GRUB_COMMAND_FLAG_BOTH, + "parttool PARTITION COMMANDS", + "perform COMMANDS on partition." + " use parttool PARTITION help for the list " + " of available commands", 0); +} + +GRUB_MOD_FINI(parttool) +{ + grub_unregister_command ("parttool"); +} Index: parttool/pcpart.c =================================================================== --- parttool/pcpart.c (revision 0) +++ parttool/pcpart.c (revision 0) @@ -0,0 +1,152 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static int activate_table_handle = -1; +static int type_table_handle = -1; + +static struct grub_parttool_argdesc grub_pcpart_bootargs[] = +{ + {"boot", "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_pc_partition_mbr mbr; + + if (dev->disk->partition->offset) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition"); + + index = dev->disk->partition->index; + part = dev->disk->partition; + dev->disk->partition = 0; + + /* Read the MBR. */ + if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), (char *) &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; + } + else + mbr.entries[index].flag = 0x0; + + /* Write the MBR. */ + grub_disk_write (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr); + + dev->disk->partition = part; + + return GRUB_ERR_NONE; +} + +static struct grub_parttool_argdesc grub_pcpart_typeargs[] = +{ + {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL}, + {"hidden", "Make partition hidden", 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_pc_partition_mbr mbr; + + index = dev->disk->partition->index; + part = dev->disk->partition; + dev->disk->partition = 0; + + /* Read the parttable. */ + if (grub_disk_read (dev->disk, part->offset, 0, + sizeof (mbr), (char *) &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_pc_partition_is_empty (type) + || grub_pc_partition_is_extended (type)) + { + dev->disk->partition = part; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type"); + } + + mbr.entries[index].type = type; + + /* Write the parttable. */ + grub_disk_write (dev->disk, part->offset, 0, + sizeof (mbr), (char *) &mbr); + + dev->disk->partition = part; + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT (pcpart) +{ + (void)mod; /* To stop warning. */ + + activate_table_handle = grub_parttool_register("pc_partition_map", + grub_pcpart_boot, + grub_pcpart_bootargs); + type_table_handle = grub_parttool_register("pc_partition_map", + grub_pcpart_type, + grub_pcpart_typeargs); + +} +GRUB_MOD_FINI(pcpart) +{ + grub_parttool_unregister (activate_table_handle); + grub_parttool_unregister (type_table_handle); +} --------------050607010208010804020902--