diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-08-20 20:04:47 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2014-08-20 20:04:47 +0000 |
commit | 5f00496ef2e39b976b062f196ff01a99fd4864a4 (patch) | |
tree | 20be9cbc8f4b7ed3e616ce23552728083801e846 /usr/src/cmd/parted/parted.c | |
parent | af59b1a40df03681c1c8129aea7b1f5f52f2bcea (diff) | |
parent | 86bb58aec7165f8a0303564575c65e5a2ad58bf1 (diff) | |
download | illumos-joyent-release-20140821.tar.gz |
[illumos-gate merge]20140821release-20140821
commit 86bb58aec7165f8a0303564575c65e5a2ad58bf1
5095 panic when adding a duplicate dbuf to dn_dbufs
commit 60a61f7adabc73a7a0cb70d200ac2a6735f4a6e8
5092 env files don't need to define LOCKNAME by default
5091 illumos.sh env file's LOCKNAME definition is busted
commit 5e3f545c431ec4bce3e1b52f3f81bc9befe501f2
4989 removal of ntfsprogs and parted
commit ba3594ba9b5dd4c846c472a8d657edcb7c8109ac
5066 remove support for non-ANSI compilation
5068 Remove SCCSID() macro from <macros.h>
commit d8ccf998f9c944b8cf27ed840c376f9b79ebce5c
5087 8-bit inline atomic {add,or,and} use wrong reg constraints on x86
Manifests:
usr/src/pkg/manifests/SUNWntfsprogs.mf (torch library)
usr/src/pkg/manifests/SUNWparted.mf (torch headers)
usr/src/pkg/manifests/system-file-system-ntfsprogs.mf
usr/src/pkg/manifests/system-storage-parted.mf
Diffstat (limited to 'usr/src/cmd/parted/parted.c')
-rw-r--r-- | usr/src/cmd/parted/parted.c | 2493 |
1 files changed, 0 insertions, 2493 deletions
diff --git a/usr/src/cmd/parted/parted.c b/usr/src/cmd/parted/parted.c deleted file mode 100644 index d8e937f32e..0000000000 --- a/usr/src/cmd/parted/parted.c +++ /dev/null @@ -1,2493 +0,0 @@ -/* - parted - a frontend to libparted - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <config.h> - -#include "closeout.h" -#include "configmake.h" -#include "version-etc.h" -#include "command.h" -#include "ui.h" -#include "table.h" - -#define AUTHORS \ - "<http://parted.alioth.debian.org/cgi-bin/trac.cgi/browser/AUTHORS>" - -/* The official name of this program (e.g., no `g' prefix). */ -#define PROGRAM_NAME "parted" - -#define N_(String) String -#if ENABLE_NLS -# include <libintl.h> -# include <locale.h> -# define _(String) dgettext (PACKAGE, String) -#else -# define _(String) (String) -#endif /* ENABLE_NLS */ - -#include <parted/parted.h> -#include <parted/debug.h> - -#include <ctype.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include "xalloc.h" - -#ifdef ENABLE_MTRACE -#include <mcheck.h> -#endif - -#include <getopt.h> - -/* minimum amount of free space to leave, or maximum amount to gobble up */ -#define MIN_FREESPACE (1000 * 2) /* 1000k */ - -static int MEGABYTE_SECTORS (PedDevice* dev) -{ - return PED_MEGABYTE_SIZE / dev->sector_size; -} - -/* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -enum -{ - PRETEND_INPUT_TTY = CHAR_MAX + 1, -}; - - -typedef struct { - time_t last_update; - time_t predicted_time_left; -} TimerContext; - -static struct option options[] = { - /* name, has-arg, string-return-val, char-return-val */ - {"help", 0, NULL, 'h'}, - {"list", 0, NULL, 'l'}, - {"machine", 0, NULL, 'm'}, - {"script", 0, NULL, 's'}, - {"version", 0, NULL, 'v'}, - {"-pretend-input-tty", 0, NULL, PRETEND_INPUT_TTY}, - {NULL, 0, NULL, 0} -}; - -static char* options_help [][2] = { - {"help", N_("displays this help message")}, - {"list", N_("lists partition layout on all block devices")}, - {"machine", N_("displays machine parseable output")}, - {"script", N_("never prompts for user intervention")}, - {"version", N_("displays the version")}, - {NULL, NULL} -}; - -char *program_name; - -int opt_script_mode = 0; -int pretend_input_tty = 0; -int opt_machine_mode = 0; -int disk_is_modified = 0; -int is_toggle_mode = 0; - -static char* number_msg = N_( -"NUMBER is the partition number used by Linux. On MS-DOS disk labels, the " -"primary partitions number from 1 to 4, logical partitions from 5 onwards.\n"); - -static char* label_type_msg_start = N_("LABEL-TYPE is one of: "); -static char* flag_msg_start = N_("FLAG is one of: "); -static char* unit_msg_start = N_("UNIT is one of: "); -static char* part_type_msg = N_("PART-TYPE is one of: primary, logical, " - "extended\n"); -static char* fs_type_msg_start = N_("FS-TYPE is one of: "); -static char* start_end_msg = N_("START and END are disk locations, such as " - "4GB or 10%. Negative values count from the end of the disk. " - "For example, -1s specifies exactly the last sector.\n"); -static char* state_msg = N_("STATE is one of: on, off\n"); -static char* device_msg = N_("DEVICE is usually /dev/hda or /dev/sda\n"); -static char* name_msg = N_("NAME is any word you want\n"); -static char* resize_msg_start = N_("The partition must have one of the " - "following FS-TYPEs: "); - -static char* copyright_msg = N_( -"Copyright (C) 1998 - 2006 Free Software Foundation, Inc.\n" -"This program is free software, covered by the GNU General Public License.\n" -"\n" -"This program is distributed in the hope that it will be useful,\n" -"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" -"GNU General Public License for more details.\n\n"); - -static char* label_type_msg; -static char* flag_msg; -static char* unit_msg; - -static char* mkfs_fs_type_msg; -static char* mkpart_fs_type_msg; -static char* resize_fs_type_msg; - -static Command* commands [256] = {NULL}; -static PedTimer* g_timer; -static TimerContext timer_context; - -static int _print_list (); -static void _done (PedDevice* dev); - -static void -_timer_handler (PedTimer* timer, void* context) -{ - TimerContext* tcontext = (TimerContext*) context; - int draw_this_time; - - if (opt_script_mode || !isatty(fileno(stdout))) - return; - - if (tcontext->last_update != timer->now && timer->now > timer->start) { - tcontext->predicted_time_left - = timer->predicted_end - timer->now; - tcontext->last_update = timer->now; - draw_this_time = 1; - } else { - draw_this_time = 0; - } - - if (draw_this_time) { - wipe_line (); - - if (timer->state_name) - printf ("%s... ", timer->state_name); - printf (_("%0.f%%\t(time left %.2d:%.2d)"), - 100.0 * timer->frac, - (int) (tcontext->predicted_time_left / 60), - (int) (tcontext->predicted_time_left % 60)); - - fflush (stdout); - } -} - -static int -_partition_warn_busy (PedPartition* part) -{ - char* path; - - if (ped_partition_is_busy (part)) { - path = ped_partition_get_path (part); - ped_exception_throw ( - PED_EXCEPTION_ERROR, - PED_EXCEPTION_CANCEL, - _("Partition %s is being used. You must unmount it " - "before you modify it with Parted."), - path); - ped_free (path); - return 0; - } - return 1; -} - -static int -_disk_warn_busy (PedDisk* disk) -{ - if (ped_device_is_busy (disk->dev)) - return ped_exception_throw ( - (opt_script_mode - ? PED_EXCEPTION_ERROR - : PED_EXCEPTION_WARNING), - PED_EXCEPTION_IGNORE_CANCEL, - _("Partition(s) on %s are being used."), - disk->dev->path) == PED_EXCEPTION_IGNORE; - - return 1; -} - -static int -_partition_warn_loss () -{ - return ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_YES_NO, - _("The existing file system will be destroyed and " - "all data on the partition will be lost. Do " - "you want to continue?"), - NULL) == PED_EXCEPTION_YES; -} - -static int -_disk_warn_loss (PedDisk* disk) -{ - return ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_YES_NO, - _("The existing disk label on %s will be destroyed " - "and all data on this disk will be lost. Do you " - "want to continue?"), - disk->dev->path) == PED_EXCEPTION_YES; -} - -/* This function changes "sector" to "new_sector" if the new value lies - * within the required range. - */ -static int -snap (PedSector* sector, PedSector new_sector, PedGeometry* range) -{ - PED_ASSERT (ped_geometry_test_sector_inside (range, *sector), return 0); - if (!ped_geometry_test_sector_inside (range, new_sector)) - return 0; - *sector = new_sector; - return 1; -} - -typedef enum { - MOVE_NO = 0, - MOVE_STILL = 1, - MOVE_UP = 2, - MOVE_DOWN = 4 -} EMoves; - -enum { /* Don't change these values */ - SECT_START = 0, - SECT_END = -1 -}; - -/* Find the prefered way to adjust the sector s inside range. - * If a move isn't allowed or is out of range it can't be selected. - * what contains SECT_START if the sector to adjust is a start sector - * or SECT_END if it's an end one. - * The prefered move is to the nearest allowed boundary of the part - * partition (if at equal distance: to start if SECT_START or to end - * if SECT_END). - * The distance is returned in dist. - */ -static EMoves -prefer_snap (PedSector s, int what, PedGeometry* range, EMoves* allow, - PedPartition* part, PedSector* dist) -{ - PedSector up_dist = -1, down_dist = -1; - PedSector new_sect; - EMoves move; - - PED_ASSERT (what == SECT_START || what == SECT_END, return 0); - - if (!(*allow & (MOVE_UP | MOVE_DOWN))) { - *dist = 0; - return MOVE_STILL; - } - - if (*allow & MOVE_UP) { - new_sect = part->geom.end + 1 + what; - if (ped_geometry_test_sector_inside (range, new_sect)) - up_dist = new_sect - s; - else - *allow &= ~MOVE_UP; - } - - if (*allow & MOVE_DOWN) { - new_sect = part->geom.start + what; - if (ped_geometry_test_sector_inside (range, new_sect)) - down_dist = s - new_sect; - else - *allow &= ~MOVE_DOWN; - } - - move = MOVE_STILL; - if ((*allow & MOVE_UP) && (*allow & MOVE_DOWN)) { - if (down_dist < up_dist || (down_dist == up_dist - && what == SECT_START) ) - move = MOVE_DOWN; - else if (up_dist < down_dist || (down_dist == up_dist - && what == SECT_END) ) - move = MOVE_UP; - else - PED_ASSERT (0, return 0); - } else if (*allow & MOVE_UP) - move = MOVE_UP; - else if (*allow & MOVE_DOWN) - move = MOVE_DOWN; - - *dist = ( move == MOVE_DOWN ? down_dist : - ( move == MOVE_UP ? up_dist : - 0 ) ); - return move; -} - -/* Snaps a partition to nearby partition boundaries. This is useful for - * gobbling up small amounts of free space, and also for reinterpreting small - * changes to a partition as non-changes (eg: perhaps the user only wanted to - * resize the end of a partition). - * Note that this isn't the end of the story... this function is - * always called before the constraint solver kicks in. So you don't need to - * worry too much about inadvertantly creating overlapping partitions, etc. - */ -static void -snap_to_boundaries (PedGeometry* new_geom, PedGeometry* old_geom, - PedDisk* disk, - PedGeometry* start_range, PedGeometry* end_range) -{ - PedPartition* start_part; - PedPartition* end_part; - PedSector start = new_geom->start; - PedSector end = new_geom->end; - PedSector start_dist = -1, end_dist = -1; - EMoves start_allow, end_allow, start_want, end_want; - int adjacent; - - start_want = end_want = MOVE_NO; - start_allow = end_allow = MOVE_STILL | MOVE_UP | MOVE_DOWN; - - start_part = ped_disk_get_partition_by_sector (disk, start); - end_part = ped_disk_get_partition_by_sector (disk, end); - adjacent = (start_part->geom.end + 1 == end_part->geom.start); - - /* If we can snap to old_geom, then we will... */ - /* and this will enforce the snapped positions */ - if (old_geom) { - if (snap (&start, old_geom->start, start_range)) - start_allow = MOVE_STILL; - if (snap (&end, old_geom->end, end_range)) - end_allow = MOVE_STILL; - } - - /* If start and end are on the same partition, we */ - /* don't allow them to cross. */ - if (start_part == end_part) { - start_allow &= ~MOVE_UP; - end_allow &= ~MOVE_DOWN; - } - - /* Let's find our way */ - start_want = prefer_snap (start, SECT_START, start_range, &start_allow, - start_part, &start_dist ); - end_want = prefer_snap (end, SECT_END, end_range, &end_allow, - end_part, &end_dist ); - - PED_ASSERT (start_dist >= 0 && end_dist >= 0, return); - - /* If start and end are on adjacent partitions, */ - /* and if they would prefer crossing, then refrain */ - /* the farthest to do so. */ - if (adjacent && start_want == MOVE_UP && end_want == MOVE_DOWN) { - if (end_dist < start_dist) { - start_allow &= ~MOVE_UP; - start_want = prefer_snap (start, SECT_START, - start_range, &start_allow, - start_part, &start_dist ); - PED_ASSERT (start_dist >= 0, return); - } else { - end_allow &= ~MOVE_DOWN; - end_want = prefer_snap (end, SECT_END, - end_range, &end_allow, - end_part, &end_dist ); - PED_ASSERT (end_dist >= 0, return); - } - } - - /* New positions */ - start = ( start_want == MOVE_DOWN ? start_part->geom.start : - ( start_want == MOVE_UP ? start_part->geom.end + 1 : - start ) ); - end = ( end_want == MOVE_DOWN ? end_part->geom.start - 1 : - ( end_want == MOVE_UP ? end_part->geom.end : - end ) ); - PED_ASSERT (ped_geometry_test_sector_inside(start_range,start), return); - PED_ASSERT (ped_geometry_test_sector_inside (end_range, end), return); - PED_ASSERT (start <= end, - PED_DEBUG (0, "start = %d, end = %d\n", start, end)); - ped_geometry_set (new_geom, start, end - start + 1); -} - -/* This functions constructs a constraint from the following information: - * start, is_start_exact, end, is_end_exact. - * - * If is_start_exact == 1, then the constraint requires start be as given in - * "start". Otherwise, the constraint does not set any requirements on the - * start. - */ -static PedConstraint* -constraint_from_start_end (PedDevice* dev, PedGeometry* range_start, - PedGeometry* range_end) -{ - return ped_constraint_new (ped_alignment_any, ped_alignment_any, - range_start, range_end, 1, dev->length); -} - -static PedConstraint* -constraint_intersect_and_destroy (PedConstraint* a, PedConstraint* b) -{ - PedConstraint* result = ped_constraint_intersect (a, b); - ped_constraint_destroy (a); - ped_constraint_destroy (b); - return result; -} - -void -help_on (char* topic) -{ - Command* cmd; - - cmd = command_get (commands, topic); - if (!cmd) return; - - command_print_help (cmd); -} - -static int -do_check (PedDevice** dev) -{ - PedDisk* disk; - PedFileSystem* fs; - PedPartition* part = NULL; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (!_partition_warn_busy (part)) - goto error_destroy_disk; - - if (!ped_disk_check (disk)) - goto error_destroy_disk; - - fs = ped_file_system_open (&part->geom); - if (!fs) - goto error_destroy_disk; - if (!ped_file_system_check (fs, g_timer)) - goto error_close_fs; - ped_file_system_close (fs); - ped_disk_destroy (disk); - return 1; - -error_close_fs: - ped_file_system_close (fs); -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_cp (PedDevice** dev) -{ - PedDisk* src_disk; - PedDisk* dst_disk; - PedPartition* src = NULL; - PedPartition* dst = NULL; - PedFileSystem* src_fs; - PedFileSystem* dst_fs; - PedFileSystemType* dst_fs_type; - - dst_disk = ped_disk_new (*dev); - if (!dst_disk) - goto error; - - src_disk = dst_disk; - if (!command_line_is_integer ()) { - if (!command_line_get_disk (_("Source device?"), &src_disk)) - goto error_destroy_disk; - } - - if (!command_line_get_partition (_("Source partition number?"), - src_disk, &src)) - goto error_destroy_disk; - if (src->type == PED_PARTITION_EXTENDED) { - ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, - _("Can't copy an extended partition.")); - goto error_destroy_disk; - } - if (!_partition_warn_busy (src)) - goto error_destroy_disk; - - if (!command_line_get_partition (_("Destination partition number?"), - dst_disk, &dst)) - goto error_destroy_disk; - if (!_partition_warn_busy (dst)) - goto error_destroy_disk; - -/* do the copy */ - src_fs = ped_file_system_open (&src->geom); - if (!src_fs) - goto error_destroy_disk; - dst_fs = ped_file_system_copy (src_fs, &dst->geom, g_timer); - if (!dst_fs) - goto error_close_src_fs; - dst_fs_type = dst_fs->type; /* may be different to src_fs->type */ - ped_file_system_close (src_fs); - ped_file_system_close (dst_fs); - -/* update the partition table, close disks */ - if (!ped_partition_set_system (dst, dst_fs_type)) - goto error_destroy_disk; - if (!ped_disk_commit (dst_disk)) - goto error_destroy_disk; - if (src_disk != dst_disk) - ped_disk_destroy (src_disk); - ped_disk_destroy (dst_disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_close_src_fs: - ped_file_system_close (src_fs); -error_destroy_disk: - if (src_disk && src_disk != dst_disk) - ped_disk_destroy (src_disk); - ped_disk_destroy (dst_disk); -error: - return 0; -} - -void -print_commands_help () -{ - int i; - - for (i=0; commands [i]; i++) - command_print_summary (commands [i]); -} - -void -print_options_help () -{ - int i; - - for (i=0; options_help [i][0]; i++) { - printf (" -%c, --%-23.23s %s\n", - options_help [i][0][0], - options_help [i][0], - _(options_help [i][1])); - } -} - -int -do_help (PedDevice** dev) -{ - if (command_line_get_word_count ()) { - char* word = command_line_pop_word (); - if (word) { - help_on (word); - free (word); - } - } else { - print_commands_help(); - } - return 1; -} - -static int -do_mklabel (PedDevice** dev) -{ - PedDisk* disk; - const PedDiskType* type = ped_disk_probe (*dev); - - ped_exception_fetch_all (); - disk = ped_disk_new (*dev); - if (!disk) ped_exception_catch (); - ped_exception_leave_all (); - - if (disk) { - if (!_disk_warn_busy (disk)) - goto error_destroy_disk; - if (!opt_script_mode && !_disk_warn_loss (disk)) - goto error_destroy_disk; - - ped_disk_destroy (disk); - } - - if (!command_line_get_disk_type (_("New disk label type?"), &type)) - goto error; - - disk = ped_disk_new_fresh (*dev, type); - if (!disk) - goto error; - - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - ped_disk_destroy (disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_mkfs (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part = NULL; - const PedFileSystemType* type = ped_file_system_type_get ("ext2"); - PedFileSystem* fs; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!opt_script_mode && !_partition_warn_loss()) - goto error_destroy_disk; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (!_partition_warn_busy (part)) - goto error_destroy_disk; - if (!command_line_get_fs_type (_("File system type?"), &type)) - goto error_destroy_disk; - - fs = ped_file_system_create (&part->geom, type, g_timer); - if (!fs) - goto error_destroy_disk; - ped_file_system_close (fs); - - if (!ped_partition_set_system (part, type)) - goto error_destroy_disk; - if (ped_partition_is_flag_available (part, PED_PARTITION_LBA)) - ped_partition_set_flag (part, PED_PARTITION_LBA, 1); - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - ped_disk_destroy (disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_mkpart (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part; - PedPartitionType part_type; - const PedFileSystemType* fs_type = ped_file_system_type_get ("ext2"); - PedSector start = 0, end = 0; - PedGeometry *range_start = NULL, *range_end = NULL; - PedConstraint* user_constraint; - PedConstraint* dev_constraint; - PedConstraint* final_constraint; - char* peek_word; - char* part_name = NULL; - char *start_usr = NULL, *end_usr = NULL; - char *start_sol = NULL, *end_sol = NULL; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) { - part_type = PED_PARTITION_NORMAL; - } else { - if (!command_line_get_part_type (_("Partition type?"), - disk, &part_type)) - goto error_destroy_disk; - } - - if (ped_disk_type_check_feature (disk->type, - PED_DISK_TYPE_PARTITION_NAME)) - part_name = command_line_get_word (_("Partition name?"), - "", NULL, 1); - - peek_word = command_line_peek_word (); - if (part_type == PED_PARTITION_EXTENDED - || (peek_word && isdigit (peek_word[0]))) { - fs_type = NULL; - } else { - if (!command_line_get_fs_type (_("File system type?"), - &fs_type)) - goto error_destroy_disk; - } - if (peek_word) - ped_free (peek_word); - - if (!command_line_get_sector (_("Start?"), *dev, &start, &range_start)) - goto error_destroy_disk; - if (!command_line_get_sector (_("End?"), *dev, &end, &range_end)) - goto error_destroy_disk; - - /* processing starts here */ - part = ped_partition_new (disk, part_type, fs_type, start, end); - if (!part) - goto error_destroy_disk; - - snap_to_boundaries (&part->geom, NULL, disk, range_start, range_end); - - /* create constraints */ - user_constraint = constraint_from_start_end (*dev, range_start, - range_end); - PED_ASSERT (user_constraint != NULL, return 0); - - dev_constraint = ped_device_get_constraint (*dev); - PED_ASSERT (dev_constraint != NULL, return 0); - - final_constraint = ped_constraint_intersect (user_constraint, - dev_constraint); - if (!final_constraint) - goto error_destroy_simple_constraints; - - /* subject to partition constraint */ - ped_exception_fetch_all(); - if (!ped_disk_add_partition (disk, part, final_constraint)) { - ped_exception_leave_all(); - - if (ped_disk_add_partition (disk, part, - ped_constraint_any (*dev))) { - start_usr = ped_unit_format (*dev, start); - end_usr = ped_unit_format (*dev, end); - start_sol = ped_unit_format (*dev, part->geom.start); - end_sol = ped_unit_format (*dev, part->geom.end); - - switch (ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_YES_NO, - _("You requested a partition from %s to %s.\n" - "The closest location we can manage is " - "%s to %s. " - "Is this still acceptable to you?"), - start_usr, end_usr, start_sol, end_sol)) - { - case PED_EXCEPTION_YES: - /* all is well in this state */ - break; - case PED_EXCEPTION_NO: - case PED_EXCEPTION_UNHANDLED: - default: - /* undo partition addition */ - goto error_remove_part; - } - } else { - goto error_remove_part; - } - } else { - ped_exception_leave_all(); - } - ped_exception_catch(); - - /* set minor attributes */ - if (part_name) - PED_ASSERT (ped_partition_set_name (part, part_name), return 0); - if (!ped_partition_set_system (part, fs_type)) - goto error_destroy_disk; - if (ped_partition_is_flag_available (part, PED_PARTITION_LBA)) - ped_partition_set_flag (part, PED_PARTITION_LBA, 1); - - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - - /* clean up */ - ped_constraint_destroy (final_constraint); - ped_constraint_destroy (user_constraint); - ped_constraint_destroy (dev_constraint); - - ped_disk_destroy (disk); - - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if (start_usr != NULL) - ped_free (start_usr); - if (end_usr != NULL) - ped_free (end_usr); - if (start_sol != NULL) - ped_free (start_sol); - if (end_sol != NULL) - ped_free (end_sol); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_remove_part: - ped_disk_remove_partition (disk, part); - ped_constraint_destroy (final_constraint); -error_destroy_simple_constraints: - ped_constraint_destroy (user_constraint); - ped_constraint_destroy (dev_constraint); - ped_partition_destroy (part); -error_destroy_disk: - ped_disk_destroy (disk); -error: - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if (start_usr != NULL) - ped_free (start_usr); - if (end_usr != NULL) - ped_free (end_usr); - if (start_sol != NULL) - ped_free (start_sol); - if (end_sol != NULL) - ped_free (end_sol); - - return 0; -} - -static int -do_mkpartfs (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part; - PedPartitionType part_type; - const PedFileSystemType* fs_type = ped_file_system_type_get ("ext2"); - PedSector start = 0, end = 0; - PedGeometry *range_start = NULL, *range_end = NULL; - PedConstraint* user_constraint; - PedConstraint* dev_constraint; - PedConstraint* final_constraint; - PedFileSystem* fs; - char* part_name = NULL; - char *start_usr = NULL, *end_usr = NULL; - char *start_sol = NULL, *end_sol = NULL; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) { - part_type = PED_PARTITION_NORMAL; - } else { - if (!command_line_get_part_type (_("Partition type?"), - disk, &part_type)) - goto error_destroy_disk; - } - - if (ped_disk_type_check_feature (disk->type, - PED_DISK_TYPE_PARTITION_NAME)) - part_name = command_line_get_word (_("Partition name?"), - "", NULL, 1); - - if (part_type == PED_PARTITION_EXTENDED) { - ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, - _("An extended partition cannot hold a file system. " - "Did you want mkpart?")); - goto error_destroy_disk; - } - - if (!command_line_get_fs_type (_("File system type?"), &fs_type)) - goto error_destroy_disk; - if (!command_line_get_sector (_("Start?"), *dev, &start, - &range_start)) - goto error_destroy_disk; - if (!command_line_get_sector (_("End?"), *dev, &end, &range_end)) - goto error_destroy_disk; - - /* attempt to create the partition now */ - part = ped_partition_new (disk, part_type, fs_type, start, end); - if (!part) - goto error_destroy_disk; - - snap_to_boundaries (&part->geom, NULL, disk, range_start, range_end); - - /* create constraints */ - user_constraint = constraint_from_start_end (*dev, range_start, - range_end); - PED_ASSERT (user_constraint != NULL, return 0); - - dev_constraint = ped_device_get_constraint (*dev); - PED_ASSERT (dev_constraint != NULL, return 0); - - final_constraint = ped_constraint_intersect (user_constraint, - dev_constraint); - if (!final_constraint) - goto error_destroy_simple_constraints; - - /* subject to partition constraint */ - ped_exception_fetch_all(); - if (!ped_disk_add_partition (disk, part, final_constraint)) { - ped_exception_leave_all(); - - if (ped_disk_add_partition (disk, part, - ped_constraint_any (*dev))) { - start_usr = ped_unit_format (*dev, start); - end_usr = ped_unit_format (*dev, end); - start_sol = ped_unit_format (*dev, part->geom.start); - end_sol = ped_unit_format (*dev, part->geom.end); - - switch (ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_YES_NO, - _("You requested a partition from %s to %s.\n" - "The closest location we can manage is " - "%s to %s. " - "Is this still acceptable to you?"), - start_usr, end_usr, start_sol, end_sol)) { - case PED_EXCEPTION_YES: - /* all is well in this state */ - break; - case PED_EXCEPTION_NO: - case PED_EXCEPTION_UNHANDLED: - default: - /* undo partition addition */ - goto error_remove_part; - } - } else { - goto error_remove_part; - } - } else { - ped_exception_leave_all(); - } - ped_exception_catch(); - - /* set LBA flag automatically if available */ - if (ped_partition_is_flag_available (part, PED_PARTITION_LBA)) - ped_partition_set_flag (part, PED_PARTITION_LBA, 1); - - /* fs creation */ - fs = ped_file_system_create (&part->geom, fs_type, g_timer); - if (!fs) - goto error_destroy_disk; - ped_file_system_close (fs); - - if (!ped_partition_set_system (part, fs_type)) - goto error_destroy_disk; - - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - - /* clean up */ - ped_constraint_destroy (final_constraint); - ped_constraint_destroy (user_constraint); - ped_constraint_destroy (dev_constraint); - - ped_disk_destroy (disk); - - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if (start_usr != NULL) - ped_free (start_usr); - if (end_usr != NULL) - ped_free (end_usr); - if (start_sol != NULL) - ped_free (start_sol); - if (end_sol != NULL) - ped_free (end_sol); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_remove_part: - ped_disk_remove_partition (disk, part); - ped_constraint_destroy (final_constraint); -error_destroy_simple_constraints: - ped_constraint_destroy (user_constraint); - ped_constraint_destroy (dev_constraint); - ped_partition_destroy (part); -error_destroy_disk: - ped_disk_destroy (disk); -error: - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if (start_usr != NULL) - ped_free (start_usr); - if (end_usr != NULL) - ped_free (end_usr); - if (start_sol != NULL) - ped_free (start_sol); - if (end_sol != NULL) - ped_free (end_sol); - - return 0; -} - -static int -do_move (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part = NULL; - PedFileSystem* fs; - PedFileSystem* fs_copy; - PedConstraint* constraint; - PedSector start = 0, end = 0; - PedGeometry *range_start = NULL, *range_end = NULL; - PedGeometry old_geom, new_geom; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (!_partition_warn_busy (part)) - goto error_destroy_disk; - if (part->type == PED_PARTITION_EXTENDED) { - ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, - _("Can't move an extended partition.")); - goto error_destroy_disk; - } - old_geom = part->geom; - fs = ped_file_system_open (&old_geom); - if (!fs) - goto error_destroy_disk; - - /* get new target */ - if (!command_line_get_sector (_("Start?"), *dev, &start, &range_start)) - goto error_close_fs; - end = start + old_geom.length - 1; - if (!command_line_get_sector (_("End?"), *dev, &end, &range_end)) - goto error_close_fs; - - /* set / test on "disk" */ - if (!ped_geometry_init (&new_geom, *dev, start, end - start + 1)) - goto error_close_fs; - snap_to_boundaries (&new_geom, NULL, disk, range_start, range_end); - - constraint = constraint_intersect_and_destroy ( - ped_file_system_get_copy_constraint (fs, *dev), - constraint_from_start_end(*dev,range_start,range_end)); - if (!ped_disk_set_partition_geom (disk, part, constraint, - new_geom.start, new_geom.end)) - goto error_destroy_constraint; - ped_constraint_destroy (constraint); - if (ped_geometry_test_overlap (&old_geom, &part->geom)) { - ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, - _("Can't move a partition onto itself. Try using " - "resize, perhaps?")); - goto error_close_fs; - } - - /* do the move */ - fs_copy = ped_file_system_copy (fs, &part->geom, g_timer); - if (!fs_copy) - goto error_close_fs; - ped_file_system_close (fs_copy); - ped_file_system_close (fs); - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - ped_disk_destroy (disk); - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_constraint: - ped_constraint_destroy (constraint); -error_close_fs: - ped_file_system_close (fs); -error_destroy_disk: - ped_disk_destroy (disk); -error: - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - return 0; -} - -static int -do_name (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part = NULL; - char* name; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - - name = command_line_get_word (_("Partition name?"), - ped_partition_get_name (part), NULL, 0); - if (!name) - goto error_destroy_disk; - if (!ped_partition_set_name (part, name)) - goto error_free_name; - free (name); - - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - ped_disk_destroy (disk); - return 1; - -error_free_name: - free (name); -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static char* -partition_print_flags (PedPartition* part) -{ - PedPartitionFlag flag; - int first_flag; - const char* name; - char* res = ped_malloc(1); - void* _res = res; - - *res = '\0'; - - first_flag = 1; - for (flag = ped_partition_flag_next (0); flag; - flag = ped_partition_flag_next (flag)) { - if (ped_partition_get_flag (part, flag)) { - if (first_flag) - first_flag = 0; - else { - _res = res; - ped_realloc (&_res, strlen (res) - + 1 + 2); - res = _res; - strncat (res, ", ", 2); - } - - name = _(ped_partition_flag_get_name (flag)); - _res = res; - ped_realloc (&_res, strlen (res) + 1 - + strlen (name)); - res = _res; - strncat (res, name, 21); - } - } - - return res; -} - -/* Prints a sector out, first in compact form, and then with a percentage. - * Eg: 32Gb (40%) - */ -static void -print_sector_compact_and_percent (PedSector sector, PedDevice* dev) -{ - char* compact; - char* percent; - - if (ped_unit_get_default() == PED_UNIT_PERCENT) - compact = ped_unit_format (dev, sector); - else - compact = ped_unit_format_custom (dev, sector, - PED_UNIT_COMPACT); - - percent = ped_unit_format_custom (dev, sector, PED_UNIT_PERCENT); - - printf ("%s (%s)\n", compact, percent); - - ped_free (compact); - ped_free (percent); -} - -static int -partition_print (PedPartition* part) -{ - PedFileSystem* fs; - PedConstraint* resize_constraint; - char* flags; - - fs = ped_file_system_open (&part->geom); - if (!fs) - return 1; - - putchar ('\n'); - - flags = partition_print_flags (part); - - printf (_("Minor: %d\n"), part->num); - printf (_("Flags: %s\n"), flags); - printf (_("File System: %s\n"), fs->type->name); - fputs (_("Size: "), stdout); - print_sector_compact_and_percent (part->geom.length, part->geom.dev); - - resize_constraint = ped_file_system_get_resize_constraint (fs); - if (resize_constraint) { - fputs (_("Minimum size: "), stdout); - print_sector_compact_and_percent (resize_constraint->min_size, - part->geom.dev); - fputs (_("Maximum size: "), stdout); - print_sector_compact_and_percent (resize_constraint->max_size, - part->geom.dev); - ped_constraint_destroy (resize_constraint); - } - - putchar ('\n'); - - ped_free (flags); - ped_file_system_close (fs); - - return 1; -} - -static int -do_print (PedDevice** dev) -{ - PedUnit default_unit; - PedDisk* disk; - Table* table; - int has_extended; - int has_name; - int has_devices_arg = 0; - int has_free_arg = 0; - int has_list_arg = 0; - int has_num_arg = 0; - char* transport[13] = {"unknown", "scsi", "ide", "dac960", - "cpqarray", "file", "ataraid", "i2o", - "ubd", "dasd", "viodasd", "sx8", "dm"}; - char* peek_word; - char* start; - char* end; - char* size; - const char* name; - char* tmp; - wchar_t* table_rendered; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - peek_word = command_line_peek_word (); - if (peek_word) { - if (strncmp (peek_word, "devices", 7) == 0) { - command_line_pop_word(); - has_devices_arg = 1; - } - else if (strncmp (peek_word, "free", 4) == 0) { - command_line_pop_word (); - has_free_arg = 1; - } - else if (strncmp (peek_word, "list", 4) == 0 || - strncmp (peek_word, "all", 3) == 0) { - command_line_pop_word(); - has_list_arg = 1; - } - else - has_num_arg = isdigit(peek_word[0]); - - ped_free (peek_word); - } - - if (has_devices_arg) { - char* dev_name; - PedDevice* current_dev = NULL; - - ped_device_probe_all(); - - while ((current_dev = ped_device_get_next(current_dev))) { - end = ped_unit_format_byte (current_dev, - current_dev->length - * current_dev->sector_size); - printf ("%s (%s)\n", current_dev->path, end); - ped_free (end); - } - - dev_name = xstrdup ((*dev)->path); - ped_device_free_all (); - - *dev = ped_device_get (dev_name); - if (!*dev) - return 0; - if (!ped_device_open (*dev)) - return 0; - - ped_free (dev_name); - - return 1; - } - - else if (has_list_arg) - return _print_list (); - - else if (has_num_arg) { - PedPartition* part = NULL; - int status = 0; - if (command_line_get_partition ("", disk, &part)) - status = partition_print (part); - ped_disk_destroy (disk); - return status; - } - - start = ped_unit_format (*dev, 0); - default_unit = ped_unit_get_default (); - end = ped_unit_format_byte (*dev, (*dev)->length * (*dev)->sector_size - - (default_unit == PED_UNIT_CHS || - default_unit == PED_UNIT_CYLINDER)); - - if (opt_machine_mode) { - switch (default_unit) { - case PED_UNIT_CHS: puts ("CHS;"); - break; - case PED_UNIT_CYLINDER: puts ("CYL;"); - break; - default: puts ("BYT;"); - break; - - } - printf ("%s:%s:%s:%lld:%lld:%s:%s;\n", - (*dev)->path, end, transport[(*dev)->type], - (*dev)->sector_size, (*dev)->phys_sector_size, - disk->type->name, (*dev)->model); - } else { - printf (_("Model: %s (%s)\n"), - (*dev)->model, transport[(*dev)->type]); - printf (_("Disk %s: %s\n"), (*dev)->path, end); - printf (_("Sector size (logical/physical): %lldB/%lldB\n"), - (*dev)->sector_size, (*dev)->phys_sector_size); - } - - ped_free (start); - ped_free (end); - - if (ped_unit_get_default () == PED_UNIT_CHS - || ped_unit_get_default () == PED_UNIT_CYLINDER) { - PedCHSGeometry* chs = &(*dev)->bios_geom; - char* cyl_size = ped_unit_format_custom (*dev, - chs->heads * chs->sectors, - PED_UNIT_KILOBYTE); - - if (opt_machine_mode) { - printf ("%d:%d:%d:%s;\n", - chs->cylinders, chs->heads, chs->sectors, cyl_size); - } else { - printf (_("BIOS cylinder,head,sector geometry: %d,%d,%d. " - "Each cylinder is %s.\n"), - chs->cylinders, chs->heads, chs->sectors, cyl_size); - } - - ped_free (cyl_size); - } - - if (!opt_machine_mode) { - printf (_("Partition Table: %s\n"), disk->type->name); - putchar ('\n'); - } - - has_extended = ped_disk_type_check_feature (disk->type, - PED_DISK_TYPE_EXTENDED); - has_name = ped_disk_type_check_feature (disk->type, - PED_DISK_TYPE_PARTITION_NAME); - - - PedPartition* part; - if (!opt_machine_mode) { - StrList *row1; - - if (ped_unit_get_default() == PED_UNIT_CHS) { - row1 = str_list_create (_("Number"), _("Start"), - _("End"), NULL); - } else { - row1 = str_list_create (_("Number"), _("Start"), - _("End"), _("Size"), NULL); - } - - if (has_extended) - str_list_append (row1, _("Type")); - - str_list_append (row1, _("File system")); - - if (has_name) - str_list_append (row1, _("Name")); - - str_list_append (row1, _("Flags")); - - - table = table_new (str_list_length(row1)); - - table_add_row_from_strlist (table, row1); - - for (part = ped_disk_next_partition (disk, NULL); part; - part = ped_disk_next_partition (disk, part)) { - - if ((!has_free_arg && !ped_partition_is_active(part)) || - part->type & PED_PARTITION_METADATA) - continue; - - tmp = ped_malloc (4); - - if (part->num >= 0) - sprintf (tmp, "%2d ", part->num); - else - sprintf (tmp, "%2s ", ""); - - StrList *row = str_list_create (tmp, NULL); - - start = ped_unit_format (*dev, part->geom.start); - end = ped_unit_format_byte ( - *dev, - (part->geom.end + 1) * (*dev)->sector_size - 1); - size = ped_unit_format (*dev, part->geom.length); - if (ped_unit_get_default() == PED_UNIT_CHS) { - str_list_append (row, start); - str_list_append (row, end); - } else { - str_list_append (row, start); - str_list_append (row, end); - str_list_append (row, size); - } - - if (!(part->type & PED_PARTITION_FREESPACE)) { - if (has_extended) { - name = ped_partition_type_get_name (part->type); - str_list_append (row, name); - } - - str_list_append (row, part->fs_type ? - part->fs_type->name : ""); - - if (has_name) { - name = ped_partition_get_name (part); - str_list_append (row, name); - } - - str_list_append (row, partition_print_flags (part)); - } else { - if (has_extended) - str_list_append (row, ""); - str_list_append (row, _("Free Space")); - if (has_name) - str_list_append (row, ""); - str_list_append (row, ""); - } - - //PED_ASSERT (row.cols == caption.cols) - table_add_row_from_strlist (table, row); - str_list_destroy (row); - } - - table_rendered = table_render (table); -#ifdef ENABLE_NLS - printf("%ls\n", table_rendered); -#else - printf("%s\n", table_rendered); -#endif - ped_free (table_rendered); - table_destroy (table); - str_list_destroy (row1); - - } else { - - for (part = ped_disk_next_partition (disk, NULL); part; - part = ped_disk_next_partition (disk, part)) { - - if ((!has_free_arg && !ped_partition_is_active(part)) || - part->type & PED_PARTITION_METADATA) - continue; - - if (part->num >= 0) - printf ("%d:", part->num); - else - fputs ("1:", stdout); - - printf ("%s:", ped_unit_format (*dev, part->geom.start)); - printf ("%s:", ped_unit_format_byte ( - *dev, - (part->geom.end + 1) * - (*dev)->sector_size - 1)); - - if (ped_unit_get_default() != PED_UNIT_CHS) - printf ("%s:", ped_unit_format (*dev, - part->geom.length)); - - if (!(part->type & PED_PARTITION_FREESPACE)) { - - if (part->fs_type) - printf ("%s:", part->fs_type->name); - else - putchar (':'); - - if (has_name) - printf ("%s:", _(ped_partition_get_name (part))); - else - putchar (':'); - - printf ("%s;\n", partition_print_flags (part)); - - } else { - puts ("free;"); - } - } - } - - ped_disk_destroy (disk); - - return 1; - - ped_disk_destroy (disk); -error: - return 0; -} - -static int -_print_list () -{ - PedDevice *current_dev = NULL; - - ped_device_probe_all(); - - while ((current_dev = ped_device_get_next(current_dev))) { - do_print (¤t_dev); - putchar ('\n'); - } - - return 1; -} - -static int -do_quit (PedDevice** dev) -{ - _done (*dev); - exit (0); -} - -static PedPartitionType -_disk_get_part_type_for_sector (PedDisk* disk, PedSector sector) -{ - PedPartition* extended; - - extended = ped_disk_extended_partition (disk); - if (!extended - || !ped_geometry_test_sector_inside (&extended->geom, sector)) - return 0; - - return PED_PARTITION_LOGICAL; -} - -/* This function checks if "part" contains a file system, and returs - * 0 if either no file system was found, or the user declined to add it. - * 1 if a file system was found, and the user chose to add it. - * -1 if the user chose to cancel the entire search. - */ -static int -_rescue_add_partition (PedPartition* part) -{ - const PedFileSystemType* fs_type; - PedGeometry* probed; - PedExceptionOption ex_opt; - PedConstraint* constraint; - char* found_start; - char* found_end; - - fs_type = ped_file_system_probe (&part->geom); - if (!fs_type) - return 0; - probed = ped_file_system_probe_specific (fs_type, &part->geom); - if (!probed) - return 0; - - if (!ped_geometry_test_inside (&part->geom, probed)) { - ped_geometry_destroy (probed); - return 0; - } - - constraint = ped_constraint_exact (probed); - if (!ped_disk_set_partition_geom (part->disk, part, constraint, - probed->start, probed->end)) { - ped_constraint_destroy (constraint); - return 0; - } - ped_constraint_destroy (constraint); - - found_start = ped_unit_format (probed->dev, probed->start); - found_end = ped_unit_format (probed->dev, probed->end); - ex_opt = ped_exception_throw ( - PED_EXCEPTION_INFORMATION, - PED_EXCEPTION_YES_NO_CANCEL, - _("A %s %s partition was found at %s -> %s. " - "Do you want to add it to the partition table?"), - fs_type->name, ped_partition_type_get_name (part->type), - found_start, found_end); - ped_geometry_destroy (probed); - ped_free (found_start); - ped_free (found_end); - - switch (ex_opt) { - case PED_EXCEPTION_CANCEL: return -1; - case PED_EXCEPTION_NO: return 0; - default: break; - } - - ped_partition_set_system (part, fs_type); - ped_disk_commit (part->disk); - return 1; -} - -/* hack: we only iterate through the start, since most (all) fs's have their - * superblocks at the start. We'll need to change this if we generalize - * for RAID, or something... - */ -static int -_rescue_pass (PedDisk* disk, PedGeometry* start_range, PedGeometry* end_range) -{ - PedSector start; - PedGeometry start_geom_exact; - PedGeometry entire_dev; - PedConstraint constraint; - PedPartition* part; - PedPartitionType part_type; - - part_type = _disk_get_part_type_for_sector ( - disk, (start_range->start + end_range->end) / 2); - - ped_geometry_init (&entire_dev, disk->dev, 0, disk->dev->length); - - ped_timer_reset (g_timer); - ped_timer_set_state_name (g_timer, _("searching for file systems")); - for (start = start_range->start; start <= start_range->end; start++) { - ped_timer_update (g_timer, 1.0 * (start - start_range->start) - / start_range->length); - - ped_geometry_init (&start_geom_exact, disk->dev, start, 1); - ped_constraint_init ( - &constraint, ped_alignment_any, ped_alignment_any, - &start_geom_exact, &entire_dev, - 1, disk->dev->length); - part = ped_partition_new (disk, part_type, NULL, start, - end_range->end); - if (!part) { - ped_constraint_done (&constraint); - continue; - } - - ped_exception_fetch_all (); - if (ped_disk_add_partition (disk, part, &constraint)) { - ped_exception_leave_all (); - switch (_rescue_add_partition (part)) { - case 1: - ped_constraint_done (&constraint); - return 1; - - case 0: - ped_disk_remove_partition (disk, part); - break; - - case -1: - goto error_remove_partition; - } - } else { - ped_exception_leave_all (); - } - ped_partition_destroy (part); - ped_constraint_done (&constraint); - } - ped_timer_update (g_timer, 1.0); - - return 1; - -error_remove_partition: - ped_disk_remove_partition (disk, part); - ped_partition_destroy (part); - ped_constraint_done (&constraint); - return 0; -} - -static int -do_rescue (PedDevice** dev) -{ - PedDisk* disk; - PedSector start = 0, end = 0; - PedSector fuzz; - PedGeometry probe_start_region; - PedGeometry probe_end_region; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_sector (_("Start?"), *dev, &start, NULL)) - goto error_destroy_disk; - if (!command_line_get_sector (_("End?"), *dev, &end, NULL)) - goto error_destroy_disk; - - fuzz = PED_MAX (PED_MIN ((end - start) / 10, MEGABYTE_SECTORS(*dev)), - MEGABYTE_SECTORS(*dev) * 16); - - ped_geometry_init (&probe_start_region, *dev, - PED_MAX(start - fuzz, 0), - PED_MIN(2 * fuzz, (*dev)->length - (start - fuzz))); - ped_geometry_init (&probe_end_region, *dev, - PED_MAX(end - fuzz, 0), - PED_MIN(2 * fuzz, (*dev)->length - (end - fuzz))); - - if (!_rescue_pass (disk, &probe_start_region, &probe_end_region)) - goto error_destroy_disk; - - ped_disk_destroy (disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_resize (PedDevice** dev) -{ - PedDisk *disk; - PedPartition *part = NULL; - PedFileSystem *fs; - PedConstraint *constraint; - PedSector start, end; - PedGeometry *range_start = NULL, *range_end = NULL; - PedGeometry new_geom; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (part->type != PED_PARTITION_EXTENDED) { - if (!_partition_warn_busy (part)) - goto error_destroy_disk; - } - - start = part->geom.start; - end = part->geom.end; - if (!command_line_get_sector (_("Start?"), *dev, &start, &range_start)) - goto error_destroy_disk; - if (!command_line_get_sector (_("End?"), *dev, &end, &range_end)) - goto error_destroy_disk; - - if (!ped_geometry_init (&new_geom, *dev, start, end - start + 1)) - goto error_destroy_disk; - snap_to_boundaries (&new_geom, &part->geom, disk, - range_start, range_end); - - if (part->type == PED_PARTITION_EXTENDED) { - constraint = constraint_from_start_end (*dev, - range_start, range_end); - if (!ped_disk_set_partition_geom (disk, part, constraint, - new_geom.start, new_geom.end)) - goto error_destroy_constraint; - ped_partition_set_system (part, NULL); - } else { - fs = ped_file_system_open (&part->geom); - if (!fs) - goto error_destroy_disk; - constraint = constraint_intersect_and_destroy ( - ped_file_system_get_resize_constraint (fs), - constraint_from_start_end ( - *dev, range_start, range_end)); - if (!ped_disk_set_partition_geom (disk, part, constraint, - new_geom.start, new_geom.end)) - goto error_close_fs; - if (!ped_file_system_resize (fs, &part->geom, g_timer)) - goto error_close_fs; - /* may have changed... eg fat16 -> fat32 */ - ped_partition_set_system (part, fs->type); - ped_file_system_close (fs); - } - - ped_disk_commit (disk); - ped_constraint_destroy (constraint); - ped_disk_destroy (disk); - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_close_fs: - ped_file_system_close (fs); -error_destroy_constraint: - ped_constraint_destroy (constraint); -error_destroy_disk: - ped_disk_destroy (disk); -error: - if (range_start != NULL) - ped_geometry_destroy (range_start); - if (range_end != NULL) - ped_geometry_destroy (range_end); - return 0; -} - -static int -do_rm (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part = NULL; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (!_partition_warn_busy (part)) - goto error_destroy_disk; - - ped_disk_delete_partition (disk, part); - ped_disk_commit (disk); - ped_disk_destroy (disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_select (PedDevice** dev) -{ - PedDevice* new_dev = *dev; - - if (!command_line_get_device (_("New device?"), &new_dev)) - return 0; - if (!ped_device_open (new_dev)) - return 0; - - ped_device_close (*dev); - *dev = new_dev; - print_using_dev (*dev); - return 1; -} - -static int -do_set (PedDevice** dev) -{ - PedDisk* disk; - PedPartition* part = NULL; - PedPartitionFlag flag; - int state; - - disk = ped_disk_new (*dev); - if (!disk) - goto error; - - if (!command_line_get_partition (_("Partition number?"), disk, &part)) - goto error_destroy_disk; - if (!command_line_get_part_flag (_("Flag to Invert?"), part, &flag)) - goto error_destroy_disk; - state = (ped_partition_get_flag (part, flag) == 0 ? 1 : 0); - - if (!is_toggle_mode) { - if (!command_line_get_state (_("New state?"), &state)) - goto error_destroy_disk; - } - - if (!ped_partition_set_flag (part, flag, state)) - goto error_destroy_disk; - if (!ped_disk_commit (disk)) - goto error_destroy_disk; - ped_disk_destroy (disk); - - if ((*dev)->type != PED_DEVICE_FILE) - disk_is_modified = 1; - - return 1; - -error_destroy_disk: - ped_disk_destroy (disk); -error: - return 0; -} - -static int -do_toggle (PedDevice **dev) -{ - int result; - - is_toggle_mode = 1; - result = do_set (dev); - is_toggle_mode = 0; - - return result; -} - -static int -do_unit (PedDevice** dev) -{ - PedUnit unit = ped_unit_get_default (); - if (!command_line_get_unit (_("Unit?"), &unit)) - return 0; - ped_unit_set_default (unit); - return 1; -} - -static int -do_version (PedDevice** dev) -{ - printf ("\n%s\n%s", - prog_name, - _(copyright_msg)); - return 1; -} - -static void -_init_messages () -{ - StrList* list; - int first; - PedFileSystemType* fs_type; - PedDiskType* disk_type; - PedPartitionFlag part_flag; - PedUnit unit; - -/* flags */ - first = 1; - list = str_list_create (_(flag_msg_start), NULL); - for (part_flag = ped_partition_flag_next (0); part_flag; - part_flag = ped_partition_flag_next (part_flag)) { - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, - _(ped_partition_flag_get_name (part_flag))); - } - str_list_append (list, "\n"); - - flag_msg = str_list_convert (list); - str_list_destroy (list); - -/* units */ - first = 1; - list = str_list_create (_(unit_msg_start), NULL); - for (unit = PED_UNIT_FIRST; unit <= PED_UNIT_LAST; unit++) { - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, ped_unit_get_name (unit)); - } - str_list_append (list, "\n"); - - unit_msg = str_list_convert (list); - str_list_destroy (list); - -/* disk type */ - list = str_list_create (_(label_type_msg_start), NULL); - - first = 1; - for (disk_type = ped_disk_type_get_next (NULL); - disk_type; disk_type = ped_disk_type_get_next (disk_type)) { - if (disk_type->ops->write == NULL) - continue; - - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, disk_type->name); - } - str_list_append (list, "\n"); - - label_type_msg = str_list_convert (list); - str_list_destroy (list); - -/* mkfs - file system types */ - list = str_list_create (_(fs_type_msg_start), NULL); - - first = 1; - for (fs_type = ped_file_system_type_get_next (NULL); - fs_type; fs_type = ped_file_system_type_get_next (fs_type)) { - if (fs_type->ops->create == NULL) - continue; - - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, fs_type->name); - } - str_list_append (list, "\n"); - - mkfs_fs_type_msg = str_list_convert (list); - str_list_destroy (list); - -/* mkpart - file system types */ - list = str_list_create (_(fs_type_msg_start), NULL); - - first = 1; - for (fs_type = ped_file_system_type_get_next (NULL); - fs_type; fs_type = ped_file_system_type_get_next (fs_type)) { - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, fs_type->name); - } - str_list_append (list, "\n"); - - mkpart_fs_type_msg = str_list_convert (list); - str_list_destroy (list); - -/* resize - file system types */ - list = str_list_create (_(resize_msg_start), NULL); - - first = 1; - for (fs_type = ped_file_system_type_get_next (NULL); - fs_type; fs_type = ped_file_system_type_get_next (fs_type)) { - if (fs_type->ops->resize == NULL) - continue; - - if (first) - first = 0; - else - str_list_append (list, ", "); - str_list_append (list, fs_type->name); - } - str_list_append (list, "\n"); - - resize_fs_type_msg = str_list_convert (list); - str_list_destroy (list); -} - -static void -_done_messages () -{ - free (flag_msg); - free (mkfs_fs_type_msg); - free (mkpart_fs_type_msg); - free (resize_fs_type_msg); - free (label_type_msg); -} - -static void -_init_commands () -{ - command_register (commands, command_create ( - str_list_create_unique ("check", _("check"), NULL), - do_check, - str_list_create ( -_("check NUMBER do a simple check on the file " - "system"), -NULL), - str_list_create (_(number_msg), NULL), 1)); - - command_register (commands, command_create ( - str_list_create_unique ("cp", _("cp"), NULL), - do_cp, - str_list_create ( -_("cp [FROM-DEVICE] FROM-NUMBER TO-NUMBER copy file system to another " - "partition"), -NULL), - str_list_create (_(number_msg), _(device_msg), NULL), 1)); - - command_register (commands, command_create ( - str_list_create_unique ("help", _("help"), NULL), - do_help, - str_list_create ( -_("help [COMMAND] print general help, or help " - "on COMMAND"), -NULL), - NULL, 1)); - - command_register (commands, command_create ( - str_list_create_unique ("mklabel", _("mklabel"), "mktable", _("mktable"), NULL), - do_mklabel, - str_list_create ( -_("mklabel,mktable LABEL-TYPE create a new disklabel " - "(partition table)"), -NULL), - str_list_create (label_type_msg, NULL), 1)); - - command_register (commands, command_create ( - str_list_create_unique ("mkfs", _("mkfs"), NULL), - do_mkfs, - str_list_create ( -_("mkfs NUMBER FS-TYPE make a FS-TYPE file " - "system on partititon NUMBER"), -NULL), - str_list_create (_(number_msg), _(mkfs_fs_type_msg), NULL), 1)); - - command_register (commands, command_create ( - str_list_create_unique ("mkpart", _("mkpart"), NULL), - do_mkpart, - str_list_create ( -_("mkpart PART-TYPE [FS-TYPE] START END make a partition"), -NULL), - str_list_create (_(part_type_msg), - _(mkpart_fs_type_msg), - _(start_end_msg), - "\n", -_("'mkpart' makes a partition without creating a new file system on the " - "partition. FS-TYPE may be specified to set an appropriate partition ID.\n"), -NULL), 1)); - - command_register (commands, command_create ( - str_list_create_unique ("mkpartfs", _("mkpartfs"), NULL), - do_mkpartfs, - str_list_create ( -_("mkpartfs PART-TYPE FS-TYPE START END make a partition with a " - "file system"), -NULL), - str_list_create (_(part_type_msg), _(start_end_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("move", _("move"), NULL), - do_move, - str_list_create ( -_("move NUMBER START END move partition NUMBER"), -NULL), - str_list_create (_(number_msg), _(start_end_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("name", _("name"), NULL), - do_name, - str_list_create ( -_("name NUMBER NAME name partition NUMBER as NAME"), -NULL), - str_list_create (_(number_msg), _(name_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("print", _("print"), NULL), - do_print, - str_list_create ( -_("print [devices|free|list,all|NUMBER] display the partition table, " - "available devices, free space, all found partitions, or a particular " - "partition"), -NULL), - str_list_create ( -_("Without arguments, 'print' displays the entire partition table. However " - "with the following arguments it performs various other actions.\n"), -_(" devices : display all active block devices\n"), -_(" free : display information about free unpartitioned space on the " - "current block device\n"), -_(" list, all : display the partition tables of all active block devices\n"), -_(" NUMBER : display more detailed information about this particular " - "partition\n"), -NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("quit", _("quit"), NULL), - do_quit, - str_list_create ( -_("quit exit program"), -NULL), - NULL, 1)); - -command_register (commands, command_create ( - str_list_create_unique ("rescue", _("rescue"), NULL), - do_rescue, - str_list_create ( -_("rescue START END rescue a lost partition near " -"START and END"), -NULL), - str_list_create (_(start_end_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("resize", _("resize"), NULL), - do_resize, - str_list_create ( -_("resize NUMBER START END resize partition NUMBER and " -"its file system"), -NULL), - str_list_create (_(number_msg), - _(start_end_msg), - _(resize_fs_type_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("rm", _("rm"), NULL), - do_rm, - str_list_create ( -_("rm NUMBER delete partition NUMBER"), -NULL), - str_list_create (_(number_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("select", _("select"), NULL), - do_select, - str_list_create ( -_("select DEVICE choose the device to edit"), -NULL), - str_list_create (_(device_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("set", _("set"), NULL), - do_set, - str_list_create ( -_("set NUMBER FLAG STATE change the FLAG on partition " - "NUMBER"), -NULL), - str_list_create (_(number_msg), flag_msg, _(state_msg), NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("toggle", _("toggle"), NULL), - do_toggle, - str_list_create ( -_("toggle [NUMBER [FLAG]] toggle the state of FLAG on " - "partition NUMBER"), -NULL), - str_list_create (_(number_msg), flag_msg, NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("unit", _("unit"), NULL), - do_unit, - str_list_create ( -_("unit UNIT set the default unit to UNIT"), -NULL), - str_list_create (unit_msg, NULL), 1)); - -command_register (commands, command_create ( - str_list_create_unique ("version", _("version"), NULL), - do_version, - str_list_create ( -_("version display the version number " -"and copyright information of GNU Parted"), -NULL), - str_list_create ( -_("'version' displays copyright and version information corresponding to this " -"copy of GNU Parted\n"), -NULL), 1)); - -} - -static void -_done_commands () -{ -Command** walk; - -for (walk = commands; *walk; walk++) { - command_destroy (*walk); - *walk = NULL; -} -} - -static void -_init_i18n () -{ -/* intialize i18n */ -#ifdef ENABLE_NLS -setlocale(LC_ALL, ""); -bindtextdomain(PACKAGE, LOCALEDIR); -textdomain(PACKAGE); -#endif /* ENABLE_NLS */ -} - -void -_version () -{ - version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, VERSION, AUTHORS, - (char *) NULL); -} - -static int -_parse_options (int* argc_ptr, char*** argv_ptr) -{ -int opt, help = 0, list = 0, version = 0, wrong = 0; - -while (1) -{ - opt = getopt_long (*argc_ptr, *argv_ptr, "hilmsv", - options, NULL); - if (opt == -1) - break; - - switch (opt) { - case 'h': help = 1; break; - case 'l': list = 1; break; - case 'm': opt_machine_mode = 1; break; - case 's': opt_script_mode = 1; break; - case 'v': version = 1; break; - case PRETEND_INPUT_TTY: - pretend_input_tty = 1; - break; - default: wrong = 1; break; - } -} - -if (wrong == 1) { - fprintf (stderr, - _("Usage: %s [-hlmsv] [DEVICE [COMMAND [PARAMETERS]]...]\n"), - program_name); - return 0; -} - -if (version == 1) { - _version (); - exit (EXIT_SUCCESS); -} - -if (help == 1) { - help_msg (); - exit (EXIT_SUCCESS); -} - -if (list == 1) { - _print_list (); - exit (EXIT_SUCCESS); -} - -*argc_ptr -= optind; -*argv_ptr += optind; -return 1; -} - -static PedDevice* -_choose_device (int* argc_ptr, char*** argv_ptr) -{ -PedDevice* dev; - -/* specified on comand line? */ -if (*argc_ptr) { - dev = ped_device_get ((*argv_ptr) [0]); - if (!dev) - return NULL; - (*argc_ptr)--; - (*argv_ptr)++; -} else { -retry: - ped_device_probe_all (); - dev = ped_device_get_next (NULL); - if (!dev) { - if (ped_exception_throw (PED_EXCEPTION_ERROR, - PED_EXCEPTION_RETRY_CANCEL, - _("No device found")) - == PED_EXCEPTION_RETRY) - goto retry; - else - return NULL; - } -} - -if (!ped_device_open (dev)) - return NULL; -return dev; -} - -static PedDevice* -_init (int* argc_ptr, char*** argv_ptr) -{ -PedDevice* dev; - -#ifdef ENABLE_MTRACE -mtrace(); -#endif - -_init_i18n (); -if (!init_ui ()) - goto error; -_init_messages (); -_init_commands (); - -if (!_parse_options (argc_ptr, argv_ptr)) - goto error_done_commands; - -#ifdef HAVE_GETUID - if (getuid() != 0 && !opt_script_mode) { - puts (_("WARNING: You are not superuser. Watch out for " - "permissions.")); - } -#endif - -dev = _choose_device (argc_ptr, argv_ptr); -if (!dev) - goto error_done_commands; - -g_timer = ped_timer_new (_timer_handler, &timer_context); -if (!g_timer) - goto error_done_commands; -timer_context.last_update = 0; - -return dev; - -error_done_commands: -_done_commands (); -_done_messages (); -done_ui (); -error: -return NULL; -} - -static void -_done (PedDevice* dev) -{ -if (dev->boot_dirty && dev->type != PED_DEVICE_FILE) { - ped_exception_throw ( - PED_EXCEPTION_WARNING, - PED_EXCEPTION_OK, - _("You should reinstall your boot loader before " - "rebooting. Read section 4 of the Parted User " - "documentation for more information.")); -} - -#if !defined(__sun) -if (!opt_script_mode && !opt_machine_mode && disk_is_modified) { - ped_exception_throw ( - PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK, - _("You may need to update /etc/fstab.\n")); -} -#endif - -ped_device_close (dev); - -ped_timer_destroy (g_timer); -_done_commands (); -_done_messages (); -done_ui(); -} - -int -main (int argc, char** argv) -{ - PedDevice* dev; - int status; - - program_name = argv[0]; - atexit (close_stdout); - - dev = _init (&argc, &argv); - if (!dev) - return 1; - - if (argc || opt_script_mode) - status = non_interactive_mode (&dev, commands, argc, argv); - else - status = interactive_mode (&dev, commands); - - _done (dev); - - return !status; -} |