/*
parted - a frontend to libparted
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2003, 2005-2008 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
+ 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,
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
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
+#include <stdbool.h>
#include "closeout.h"
#include "configmake.h"
#include "version-etc.h"
#include "command.h"
#include "ui.h"
+#include "progname.h"
#include "table.h"
#define AUTHORS \
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
+#include "xalloc.h"
#ifdef ENABLE_MTRACE
#include <mcheck.h>
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[] = {
+static const struct option const 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] = {
+static const char *const options_help [][2] = {
{"help", N_("displays this help message")},
{"list", N_("lists partition layout on all block devices")},
{"machine", N_("displays machine parseable output")},
{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_(
+static const 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, "
+static const char* label_type_msg_start = N_("LABEL-TYPE is one of: ");
+static const char* flag_msg_start = N_("FLAG is one of: ");
+static const char* unit_msg_start = N_("UNIT is one of: ");
+static const 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 "
+static const char* fs_type_msg_start = N_("FS-TYPE is one of: ");
+static const 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 "
+static const char* state_msg = N_("STATE is one of: on, off\n");
+static const char* device_msg = N_("DEVICE is usually /dev/hda or /dev/sda\n");
+static const char* name_msg = N_("NAME is any word you want\n");
+static const char* resize_msg_start = N_("The partition must have one of the "
"following FS-TYPEs: ");
-static char* copyright_msg = N_(
+static const 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"
static PedTimer* g_timer;
static TimerContext timer_context;
-static int _print_list (int cli);
+static int _print_list ();
static void _done (PedDevice* dev);
static void
_("Partition %s is being used. You must unmount it "
"before you modify it with Parted."),
path);
- ped_free (path);
+ free (path);
return 0;
}
return 1;
{
if (ped_device_is_busy (disk->dev))
return ped_exception_throw (
- PED_EXCEPTION_WARNING,
+ (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;
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:
if (disk) {
if (!_disk_warn_busy (disk))
goto error_destroy_disk;
-
- if (!_disk_warn_loss (disk))
+ if (!opt_script_mode && !_disk_warn_loss (disk))
goto error_destroy_disk;
ped_disk_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:
if (!disk)
goto error;
- if (!_partition_warn_loss())
+ 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))
+ 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 (!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:
goto error_destroy_disk;
}
+ /* The undocumented feature that mkpart sometimes takes a
+ partition name is next to useless, at least with a dvh
+ partition table, since it makes the "mkpart" command
+ fail unconditionally for a primary partition. E.g.,
+ mkpart primary any-name xfs 4096s 5000s
+ requires the name, yet always fails, saying that only
+ logical partitions may have names.
+ If you want a name, use parted's separate "name" command. */
+
if (ped_disk_type_check_feature (disk->type,
- PED_DISK_TYPE_PARTITION_NAME))
+ PED_DISK_TYPE_PARTITION_NAME)
+ && ! (strcmp (disk->type->name, "dvh") == 0
+ && part_type != PED_PARTITION_LOGICAL))
part_name = command_line_get_word (_("Partition name?"),
- "", NULL, 1);
-
+ "", NULL, 1);
+
peek_word = command_line_peek_word ();
if (part_type == PED_PARTITION_EXTENDED
|| (peek_word && isdigit (peek_word[0]))) {
&fs_type))
goto error_destroy_disk;
}
- if (peek_word)
- ped_free (peek_word);
+ free (peek_word);
if (!command_line_get_sector (_("Start?"), *dev, &start, &range_start))
goto error_destroy_disk;
final_constraint = ped_constraint_intersect (user_constraint,
dev_constraint);
+ ped_constraint_destroy (user_constraint);
+ ped_constraint_destroy (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)) {
+ bool added_ok = ped_disk_add_partition (disk, part, final_constraint);
+ ped_constraint_destroy (final_constraint);
+ if (!added_ok) {
ped_exception_leave_all();
if (ped_disk_add_partition (disk, part,
} else {
goto error_remove_part;
}
+ } else {
+ ped_exception_leave_all();
}
ped_exception_catch();
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)
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);
+ free (start_usr);
+ free (end_usr);
+ free (start_sol);
+ 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);
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);
+ free (start_usr);
+ free (end_usr);
+ free (start_sol);
+ free (end_sol);
return 0;
}
final_constraint = ped_constraint_intersect (user_constraint,
dev_constraint);
+ ped_constraint_destroy (user_constraint);
+ ped_constraint_destroy (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)) {
+ bool added_ok = ped_disk_add_partition (disk, part, final_constraint);
+ ped_constraint_destroy (final_constraint);
+ if (!added_ok) {
ped_exception_leave_all();
if (ped_disk_add_partition (disk, part,
} else {
goto error_remove_part;
}
+ } else {
+ ped_exception_leave_all();
}
ped_exception_catch();
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_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);
+ free (start_usr);
+ free (end_usr);
+ free (start_sol);
+ 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);
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);
+ free (start_usr);
+ free (end_usr);
+ free (start_sol);
+ free (end_sol);
return 0;
}
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:
printf ("%s (%s)\n", compact, percent);
- ped_free (compact);
- ped_free (percent);
+ free (compact);
+ free (percent);
}
static int
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);
putchar ('\n');
- ped_free (flags);
+ 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"};
+ const char *const transport[14] = {"unknown", "scsi", "ide", "dac960",
+ "cpqarray", "file", "ataraid", "i2o",
+ "ubd", "dasd", "viodasd", "sx8", "dm",
+ "xvd"};
char* peek_word;
char* start;
char* end;
char* size;
const char* name;
char* tmp;
+ char* flags;
wchar_t* table_rendered;
disk = ped_disk_new (*dev);
else
has_num_arg = isdigit(peek_word[0]);
- ped_free (peek_word);
+ free (peek_word);
}
if (has_devices_arg) {
current_dev->length
* current_dev->sector_size);
printf ("%s (%s)\n", current_dev->path, end);
- ped_free (end);
+ free (end);
}
- dev_name = strdup ((*dev)->path);
+ dev_name = xstrdup ((*dev)->path);
ped_device_free_all ();
*dev = ped_device_get (dev_name);
if (!ped_device_open (*dev))
return 0;
- ped_free (dev_name);
+ free (dev_name);
return 1;
}
else if (has_list_arg)
- return _print_list (0);
+ return _print_list ();
else if (has_num_arg) {
PedPartition* part = NULL;
}
start = ped_unit_format (*dev, 0);
+ default_unit = ped_unit_get_default ();
end = ped_unit_format_byte (*dev, (*dev)->length * (*dev)->sector_size
- - 1 );
-
+ - (default_unit == PED_UNIT_CHS ||
+ default_unit == PED_UNIT_CYLINDER));
+
if (opt_machine_mode) {
- switch (ped_unit_get_default ()) {
+ switch (default_unit) {
case PED_UNIT_CHS: puts ("CHS;");
break;
case PED_UNIT_CYLINDER: puts ("CYL;");
(*dev)->sector_size, (*dev)->phys_sector_size);
}
- ped_free (start);
- ped_free (end);
+ free (start);
+ free (end);
if (ped_unit_get_default () == PED_UNIT_CHS
|| ped_unit_get_default () == PED_UNIT_CYLINDER) {
chs->cylinders, chs->heads, chs->sectors, cyl_size);
}
- ped_free (cyl_size);
+ free (cyl_size);
}
if (!opt_machine_mode) {
PedPartition* part;
if (!opt_machine_mode) {
+ StrList *row1;
if (ped_unit_get_default() == PED_UNIT_CHS) {
- row = str_list_create (_("Number"), _("Start"),
+ row1 = str_list_create (_("Number"), _("Start"),
_("End"), NULL);
} else {
- row = str_list_create (_("Number"), _("Start"),
+ row1 = str_list_create (_("Number"), _("Start"),
_("End"), _("Size"), NULL);
}
if (has_extended)
- str_list_append (row, _("Type"));
+ str_list_append (row1, _("Type"));
- str_list_append (row, _("File system"));
+ str_list_append (row1, _("File system"));
if (has_name)
- str_list_append (row, _("Name"));
-
- str_list_append (row, _("Flags"));
+ str_list_append (row1, _("Name"));
+ str_list_append (row1, _("Flags"));
- table = table_new (str_list_length(row));
- table_add_row_from_strlist (table, row);
+ 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)) {
else
sprintf (tmp, "%2s ", "");
- row = str_list_create (tmp, NULL);
+ StrList *row = str_list_create (tmp, NULL);
start = ped_unit_format (*dev, part->geom.start);
end = ped_unit_format_byte (
if (!(part->type & PED_PARTITION_FREESPACE)) {
if (has_extended) {
- name =
- _(ped_partition_type_get_name (part->type));
+ name = ped_partition_type_get_name (part->type);
str_list_append (row, name);
}
part->fs_type->name : "");
if (has_name) {
- name = _(ped_partition_get_name (part));
+ name = ped_partition_get_name (part);
str_list_append (row, name);
}
- str_list_append (row, partition_print_flags (part));
+ flags = partition_print_flags (part);
+ str_list_append (row, flags);
+ free (flags);
} else {
if (has_extended)
str_list_append (row, "");
//PED_ASSERT (row.cols == caption.cols)
table_add_row_from_strlist (table, row);
+ str_list_destroy (row);
+ free (tmp);
+ free (start);
+ free (end);
+ free (size);
}
table_rendered = table_render (table);
#else
printf("%s\n", table_rendered);
#endif
- ped_free (table_rendered);
+ free (table_rendered);
table_destroy (table);
+ str_list_destroy (row1);
} else {
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));
+ char *s = ped_unit_format (*dev, part->geom.start);
+ printf ("%s:", s);
+ free (s);
+ s = ped_unit_format_byte (*dev,
+ (part->geom.end + 1) *
+ (*dev)->sector_size - 1);
+ printf ("%s:", s);
+ free (s);
+
+ if (ped_unit_get_default() != PED_UNIT_CHS) {
+ s = ped_unit_format (*dev, part->geom.length);
+ printf ("%s:", s);
+ free (s);
+ }
if (!(part->type & PED_PARTITION_FREESPACE)) {
}
static int
-_print_list (int cli)
+_print_list ()
{
PedDevice *current_dev = NULL;
putchar ('\n');
}
- if(cli)
- exit(0);
-
return 1;
}
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);
+ free (found_start);
+ free (found_end);
switch (ex_opt) {
case PED_EXCEPTION_CANCEL: return -1;
goto error_destroy_disk;
ped_disk_destroy (disk);
+
+ if ((*dev)->type != PED_DEVICE_FILE)
+ disk_is_modified = 1;
+
return 1;
error_destroy_disk:
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_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:
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:
str_list_create_unique ("help", _("help"), NULL),
do_help,
str_list_create (
-_("help [COMMAND] prints general help, or help "
+_("help [COMMAND] print general help, or help "
"on COMMAND"),
NULL),
NULL, 1));
_(mkpart_fs_type_msg),
_(start_end_msg),
"\n",
-_("mkpart makes a partition without creating a new file system on the "
+_("'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));
do_print,
str_list_create (
_("print [devices|free|list,all|NUMBER] display the partition table, "
- "a partition, or all devices"),
+ "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 the various other actions.\n"),
-_("a. devices : display all active block devices\n"),
-_("b. free : display information about free unpartitioned space on the "
+_("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"),
-_("c. list,all: display partition tables of all active block devices\n"),
-_("d. NUMBER : display more detail information about particular partition\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 ("version", _("version"), NULL),
do_version,
str_list_create (
-_("version displays the current version "
-"of GNU Parted and copyright information"),
+_("version display the version number "
+"and copyright information of GNU Parted"),
NULL),
str_list_create (
-_("version displays copyright and version information corressponding to this "
+_("'version' displays copyright and version information corresponding to this "
"copy of GNU Parted\n"),
NULL), 1));
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, VERSION, AUTHORS,
(char *) NULL);
- exit (EXIT_SUCCESS);
}
static int
_parse_options (int* argc_ptr, char*** argv_ptr)
{
-int opt;
+int opt, help = 0, list = 0, version = 0, wrong = 0;
while (1)
{
break;
switch (opt) {
- case 'h': help_msg (); break;
- case 'l': _print_list(1); break;
+ 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 (); 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;
goto error_done_commands;
#ifdef HAVE_GETUID
- if (getuid() != 0) {
+ if (getuid() != 0 && !opt_script_mode) {
puts (_("WARNING: You are not superuser. Watch out for "
"permissions."));
}
"rebooting. Read section 4 of the Parted User "
"documentation for more information."));
}
-if (dev->type != PED_DEVICE_FILE && !opt_script_mode && !opt_machine_mode) {
+if (!opt_script_mode && !opt_machine_mode && disk_is_modified) {
ped_exception_throw (
PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,
- _("Don't forget to update /etc/fstab, if "
- "necessary.\n"));
+ _("You may need to update /etc/fstab.\n"));
}
ped_device_close (dev);
PedDevice* dev;
int status;
- program_name = argv[0];
+ set_program_name (argv[0]);
atexit (close_stdout);
dev = _init (&argc, &argv);