OSDN Git Service

use gnulib's progname module
[android-x86/external-parted.git] / parted / parted.c
index fb23462..9f79ea4 100644 (file)
@@ -1,11 +1,10 @@
 /*
     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 \
@@ -50,6 +50,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <limits.h>
+#include "xalloc.h"
 
 #ifdef ENABLE_MTRACE
 #include <mcheck.h>
@@ -65,23 +67,31 @@ 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[] = {
+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")},
@@ -90,32 +100,32 @@ static char*    options_help [][2] = {
         {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"
@@ -136,7 +146,7 @@ static Command* commands [256] = {NULL};
 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
@@ -184,7 +194,7 @@ _partition_warn_busy (PedPartition* part)
                         _("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;
@@ -195,7 +205,9 @@ _disk_warn_busy (PedDisk* disk)
 {
         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;
@@ -526,6 +538,10 @@ do_cp (PedDevice** dev)
         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:
@@ -589,8 +605,7 @@ do_mklabel (PedDevice** dev)
         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);
@@ -606,6 +621,10 @@ do_mklabel (PedDevice** dev)
         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:
@@ -626,14 +645,14 @@ do_mkfs (PedDevice** dev)
         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);
@@ -648,6 +667,10 @@ do_mkfs (PedDevice** dev)
         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:
@@ -685,11 +708,22 @@ do_mkpart (PedDevice** dev)
                         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]))) {
@@ -699,8 +733,7 @@ do_mkpart (PedDevice** dev)
                                                &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;
@@ -724,12 +757,16 @@ do_mkpart (PedDevice** dev)
 
         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,
@@ -760,6 +797,8 @@ do_mkpart (PedDevice** dev)
                 } else {
                         goto error_remove_part;
                 }
+        } else {
+                ped_exception_leave_all();
         }
         ped_exception_catch();
 
@@ -775,10 +814,6 @@ do_mkpart (PedDevice** dev)
                 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)
@@ -786,23 +821,19 @@ do_mkpart (PedDevice** dev)
         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);
@@ -812,14 +843,10 @@ error:
         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;
 }
@@ -890,12 +917,16 @@ do_mkpartfs (PedDevice** dev)
 
         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,
@@ -925,6 +956,8 @@ do_mkpartfs (PedDevice** dev)
                 } else {
                         goto error_remove_part;
                 }
+        } else {
+                ped_exception_leave_all();
         }
         ped_exception_catch();
 
@@ -945,9 +978,6 @@ do_mkpartfs (PedDevice** dev)
                 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);
 
@@ -956,23 +986,19 @@ do_mkpartfs (PedDevice** dev)
         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);
@@ -982,14 +1008,10 @@ error:
         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;
 }
@@ -1063,6 +1085,10 @@ do_move (PedDevice** dev)
                 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:
@@ -1170,8 +1196,8 @@ print_sector_compact_and_percent (PedSector sector, PedDevice* dev)
 
         printf ("%s (%s)\n", compact, percent);
 
-        ped_free (compact);
-        ped_free (percent);
+        free (compact);
+        free (percent);
 }
 
 static int
@@ -1188,7 +1214,7 @@ partition_print (PedPartition* part)
         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);
@@ -1208,7 +1234,7 @@ partition_print (PedPartition* part)
 
         putchar ('\n');
 
-        ped_free (flags);
+        free (flags);
         ped_file_system_close (fs);
 
         return 1;
@@ -1217,24 +1243,26 @@ partition_print (PedPartition* part)
 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);
@@ -1259,7 +1287,7 @@ do_print (PedDevice** dev)
                 else
                         has_num_arg = isdigit(peek_word[0]);
 
-                ped_free (peek_word);
+                free (peek_word);
         }
 
         if (has_devices_arg) {
@@ -1273,10 +1301,10 @@ do_print (PedDevice** dev)
                                              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);
@@ -1285,13 +1313,13 @@ do_print (PedDevice** dev)
                 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;
@@ -1303,11 +1331,13 @@ do_print (PedDevice** dev)
         }
 
         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;");
@@ -1328,8 +1358,8 @@ do_print (PedDevice** dev)
                     (*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) {
@@ -1347,7 +1377,7 @@ do_print (PedDevice** dev)
                             chs->cylinders, chs->heads, chs->sectors, cyl_size);
                 }
 
-                ped_free (cyl_size);
+                free (cyl_size);
         }
 
         if (!opt_machine_mode) {
@@ -1363,30 +1393,30 @@ do_print (PedDevice** dev)
         
         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)) {
@@ -1402,7 +1432,7 @@ do_print (PedDevice** dev)
                     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 (
@@ -1420,8 +1450,7 @@ do_print (PedDevice** dev)
 
                     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);
                             }
 
@@ -1429,11 +1458,13 @@ do_print (PedDevice** dev)
                                              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, "");
@@ -1445,6 +1476,11 @@ do_print (PedDevice** dev)
 
                     //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); 
@@ -1453,8 +1489,9 @@ do_print (PedDevice** dev)
 #else
             printf("%s\n", table_rendered);
 #endif
-            ped_free (table_rendered);
+            free (table_rendered);
             table_destroy (table);
+            str_list_destroy (row1);
 
         } else {
     
@@ -1470,15 +1507,20 @@ do_print (PedDevice** dev)
                 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)) {
 
@@ -1510,7 +1552,7 @@ error:
 }
 
 static int
-_print_list (int cli)
+_print_list ()
 {
         PedDevice *current_dev = NULL;
 
@@ -1521,9 +1563,6 @@ _print_list (int cli)
                 putchar ('\n');
         }    
 
-        if(cli)
-                exit(0);
-
         return 1;
 }
 
@@ -1592,8 +1631,8 @@ _rescue_add_partition (PedPartition* part)
                 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;
@@ -1707,6 +1746,10 @@ do_rescue (PedDevice** dev)
                 goto error_destroy_disk;
 
         ped_disk_destroy (disk);
+
+        if ((*dev)->type != PED_DEVICE_FILE)
+                disk_is_modified = 1;
+
         return 1;
 
 error_destroy_disk:
@@ -1781,6 +1824,10 @@ do_resize (PedDevice** dev)
                 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:
@@ -1815,6 +1862,10 @@ do_rm (PedDevice** dev)
         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:
@@ -1867,6 +1918,10 @@ do_set (PedDevice** dev)
        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:
@@ -2061,7 +2116,7 @@ NULL),
                 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));
@@ -2094,7 +2149,7 @@ NULL),
                                  _(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));
 
@@ -2128,16 +2183,18 @@ command_register (commands, command_create (
         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 (
@@ -2214,11 +2271,11 @@ 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));
 
@@ -2251,13 +2308,12 @@ _version ()
 {
   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)
 {
@@ -2267,14 +2323,40 @@ 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;
@@ -2331,7 +2413,7 @@ if (!_parse_options (argc_ptr, argv_ptr))
         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."));
         }
@@ -2367,11 +2449,10 @@ if (dev->boot_dirty && dev->type != PED_DEVICE_FILE) {
           "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);
@@ -2388,7 +2469,7 @@ main (int argc, char** argv)
         PedDevice*      dev;
         int             status;
 
-        program_name = argv[0];
+        set_program_name (argv[0]);
         atexit (close_stdout);
 
         dev = _init (&argc, &argv);