/*
    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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#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>

#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 (
                        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 (!opt_script_mode) {
                        if (!_disk_warn_busy (disk))
                                goto error_destroy_disk;
                        if (!_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))
                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;
                }
        }
        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;
                }
        }
        ped_exception_catch();
        ped_exception_leave_all();

        /* 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;
        StrList*        row;
        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 = strdup ((*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) {

            if (ped_unit_get_default() == PED_UNIT_CHS) {
                    row = str_list_create (_("Number"), _("Start"),
                                               _("End"), NULL);
            } else {
                    row = str_list_create (_("Number"), _("Start"),
                                               _("End"), _("Size"), NULL);
            }

            if (has_extended)
                    str_list_append (row, _("Type"));

            str_list_append (row, _("File system"));

            if (has_name)
                    str_list_append (row, _("Name"));

            str_list_append (row, _("Flags"));


            table = table_new (str_list_length(row));

            table_add_row_from_strlist (table, row);


            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 ", "");

                    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);
            }

            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);

        } 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 (&current_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 ()
{
    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 (!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"));
}

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;
}
