OSDN Git Service

use gnulib's progname module
[android-x86/external-parted.git] / parted / parted.c
index 99b9f28..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 \
@@ -51,6 +51,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <limits.h>
+#include "xalloc.h"
 
 #ifdef ENABLE_MTRACE
 #include <mcheck.h>
@@ -79,7 +80,7 @@ typedef struct {
         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'},
@@ -90,7 +91,7 @@ static struct option    options[] = {
         {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")},
@@ -99,34 +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"
@@ -195,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;
@@ -206,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;
@@ -602,12 +603,10 @@ do_mklabel (PedDevice** dev)
         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;
-                }
+                if (!_disk_warn_busy (disk))
+                        goto error_destroy_disk;
+                if (!opt_script_mode && !_disk_warn_loss (disk))
+                        goto error_destroy_disk;
 
                 ped_disk_destroy (disk);
         }
@@ -646,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);
@@ -709,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]))) {
@@ -723,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;
@@ -748,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,
@@ -784,6 +797,8 @@ do_mkpart (PedDevice** dev)
                 } else {
                         goto error_remove_part;
                 }
+        } else {
+                ped_exception_leave_all();
         }
         ped_exception_catch();
 
@@ -799,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)
@@ -810,14 +821,10 @@ 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;
@@ -826,10 +833,7 @@ do_mkpart (PedDevice** dev)
 
 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);
@@ -839,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;
 }
@@ -917,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,
@@ -952,9 +956,10 @@ do_mkpartfs (PedDevice** dev)
                 } else {
                         goto error_remove_part;
                 }
+        } else {
+                ped_exception_leave_all();
         }
         ped_exception_catch();
-        ped_exception_leave_all();
 
         /* set LBA flag automatically if available */
         if (ped_partition_is_flag_available (part, PED_PARTITION_LBA))
@@ -973,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);
 
@@ -984,14 +986,10 @@ 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;
@@ -1000,10 +998,7 @@ do_mkpartfs (PedDevice** dev)
 
 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);
@@ -1013,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;
 }
@@ -1205,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
@@ -1223,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);
@@ -1243,7 +1234,7 @@ partition_print (PedPartition* part)
 
         putchar ('\n');
 
-        ped_free (flags);
+        free (flags);
         ped_file_system_close (fs);
 
         return 1;
@@ -1255,22 +1246,23 @@ 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);
@@ -1295,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) {
@@ -1309,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);
@@ -1321,7 +1313,7 @@ do_print (PedDevice** dev)
                 if (!ped_device_open (*dev))
                         return 0;
 
-                ped_free (dev_name);
+                free (dev_name);
 
                 return 1;
         }
@@ -1366,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) {
@@ -1385,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) {
@@ -1401,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)) {
@@ -1440,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 (
@@ -1470,7 +1462,9 @@ do_print (PedDevice** dev)
                                     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, "");
@@ -1482,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); 
@@ -1490,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 {
     
@@ -1507,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)) {
 
@@ -1626,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;
@@ -2464,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);