Anonymous avatar Anonymous committed 5284ec7

Comments (0)

Files changed (2)

 #include "base.h"
 
 
+static int MEGABYTE_SECTORS (PedDevice* dev)
+{
+        return PED_MEGABYTE_SIZE / dev->sector_size;
+}
+
 struct bsdlabel {
   unsigned int magic;
   char unused[128];
 	if (!uiquery->getdisktype) {
 		if (*value) 
 			strcpy(disk_type_name,(*value)->name);
-		if (!uiquery->getstring (prompt, &disk_type_name, disk_type_list, NULL, 1))
+		if (!uiquery->getstring (prompt, &disk_type_name, disk_type_list, NULL, -1))
 			return 0;
 		if (!disk_type_name) {
 			ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
 		if(*value) {
 			strcpy(fs_type_name,(*value)->name);
 		}
-		if (!uiquery->getstring(prompt,&fs_type_name,fs_type_list,fs_type_list,1))
+		if (!uiquery->getstring(prompt,&fs_type_name,fs_type_list,NULL,-1))
 			return 0;
 		if (!fs_type_name) {
 			ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
    The parameters specify the destination partition.
    The source partition is get using a callback function prompt.
    Writes partition table to disk */
+/* If warn is set to 1, warns the user TODO: get rid of warn */
 int
-do_cp (PedDisk* dst_disk, PedPartition* dst, UICalls *uiquery)
+do_cp (PedDisk* dst_disk, PedPartition* dst, int warn, UICalls *uiquery)
 {
         PedDisk*                src_disk;
         PedDevice*              src_device;
         PedFileSystem*          src_fs;
         PedFileSystem*          dst_fs;
         PedFileSystemType*      dst_fs_type;
-	
-	if (!ask_boolean_question 
-	(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
-		return 1;
+	if (warn)
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
 
         if (!dst_disk)
                 goto error;
 /* 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))
+        if (!ped_disk_commit (dst_disk)) {
+		//if (uiquery->need_commit) uiquery->need_commit = -1;
                 goto error_destroy_disk;
+	}
+	uiquery->need_commit = 0;
         if (src_disk != dst_disk)
                 ped_disk_destroy (src_disk);
-        ped_disk_destroy (dst_disk);
+        /*ped_disk_destroy (dst_disk);*/
         return 1;
 
 error_close_src_fs:
         if (!*disk)
                 goto error;
 	
-        if (!ped_disk_commit (*disk))
-                goto error;
+        /*if (!ped_disk_commit (*disk))
+                goto error;*/
+	uiquery->need_commit = 1;
         return 1;
 
 error:
 }
 
 /* Create a filesystem. Takes filesystem type as an optional parameter */
+/* If warn is set to 1, warns the user TODO: get rid of warn */
 int
-do_mkfs (PedDisk* disk, PedPartition* part, const PedFileSystemType* type, UICalls *uiquery)
+do_mkfs (PedDisk* disk, PedPartition* part, const PedFileSystemType* type, int warn, UICalls *uiquery)
 {
 
         PedFileSystem*          fs;
-
-	if (!ask_boolean_question 
-	(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
-		return 1;
+	if (warn) {
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
+	}
 
         if (!disk)
                 goto error;
                 goto error;
         if (ped_partition_is_flag_available (part, PED_PARTITION_LBA))
                 ped_partition_set_flag (part, PED_PARTITION_LBA, 1);
-        if (!ped_disk_commit (disk))
+        if (!ped_disk_commit (disk)) {
+		//if (uiquery->need_commit) uiquery->need_commit = -1;
                 goto error;
+	}
+	uiquery->need_commit = 0;
         return 1;
 
 
         return 0;
 }
 
-/* The parameter custom is 1, then the user is asked about the start and end sector */
+/* The parameter custom is 1, then the user is asked about the start and end sector *
+ * If the parameter newpart is not NULL, it is set to the newly created partition */
 int
 do_mkpart (PedDisk* disk, PedSector start, PedSector end, int custom, PedPartitionType part_type,
-		const PedFileSystemType* fs_type, UICalls *uiquery)
+	const PedFileSystemType* fs_type, PedPartition **newpart, UICalls *uiquery)
 {
 	PedGeometry		*range_start = NULL, *range_end = NULL;
         PedPartition*            part;
 		if (part_type && part_type != PED_PARTITION_NORMAL)
 			goto error;
                 part_type = PED_PARTITION_NORMAL;
-        } else {
+        } else if (!part_type) {
                 if (!get_part_type (_("Partition type"), disk, &part_type, uiquery))
                         goto error;
         }
 
-        if (ped_disk_type_check_feature (disk->type,
-                                         PED_DISK_TYPE_PARTITION_NAME)) 
-                uiquery->getstring(_("Partition name"), &part_name, NULL, NULL, 1); 
                 
         /*peek_word = command_line_peek_word ();*/
         if (part_type == PED_PARTITION_EXTENDED) {
             /*|| (peek_word && isdigit (peek_word[0]))) {*/
                 fs_type = NULL;
-        } else {
+        } else if (!fs_type) {
                 if (!get_fs_type (_("File system type?"), &fs_type, uiquery))
                         goto error;
         }
         /*if (peek_word)
                 ped_free (peek_word);*/
 
+        if (ped_disk_type_check_feature (disk->type,
+                                         PED_DISK_TYPE_PARTITION_NAME)) 
+                uiquery->getstring(_("Partition name"), &part_name, NULL, NULL, 1); 
+
         if (!get_sector (_("Start?"), disk->dev, &start, &range_start, custom, uiquery))
                 goto error;
         if (!get_sector (_("End?"), disk->dev, &end, &range_end, custom, uiquery))
         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;
+        /*if (!ped_disk_commit (disk))
+                goto error;*/
+	uiquery->need_commit = 1;
         
         /* 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);
                 ped_free (start_sol);
         if (end_sol != NULL)
                 ped_free (end_sol);
-
+	if (newpart) *newpart = part;
         return 1;
 
 error_remove_part:
 
         return 0;
 }
+/* TODO: get rid of warn */
+int
+do_mkpartfs (PedDisk* disk, PedSector start, PedSector end, int custom, PedPartitionType part_type,
+	const PedFileSystemType* fs_type, PedPartition **newpart, int warn, UICalls *uiquery)
+{
+
+        PedPartition*            part;
+
+        
+        if (!disk)
+                return 0;
+
+	if (warn) {
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
+	}
+
+        if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) {
+		if (part_type && part_type != PED_PARTITION_NORMAL)
+			return 0;
+                part_type = PED_PARTITION_NORMAL;
+        } else if (!part_type) {
+                if (!get_part_type (_("Partition type"), disk, &part_type, uiquery))
+                        return 0;
+        }
+
+        if (part_type == PED_PARTITION_EXTENDED) {
+                ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+                        _("An extended partition cannot hold a file system."));
+                return 0;
+        }
+
+        if (!fs_type) {
+                if (!get_fs_type (_("File system type?"), &fs_type, uiquery))
+                        return 0;
+        }
+	if (!do_mkpart(disk,start,end,custom,part_type,fs_type,&part,uiquery))
+		return 0;
+	if (!do_mkfs(disk,part,fs_type,0,uiquery))
+		return 0;
+	if (newpart) *newpart = part;
+	return 1;
+
+
+}
+
+/* TODO: get rid of warn */
+static int
+do_move (PedDisk *disk, PedPartition *part, PedSector start, PedSector end, int custom, int warn, UICalls *uiquery)
+{
+       
+        PedFileSystem*  fs;
+        PedFileSystem*  fs_copy;
+        PedConstraint*  constraint;
+        /*PedSector       start = 0, end = 0;*/
+        PedGeometry     *range_start = NULL, *range_end = NULL;
+        PedGeometry     old_geom, new_geom;
+
+
+        if (!disk)
+                goto error;
+
+	if (warn) {
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
+	}
+
+	if (!part)
+        	if (!get_partition (_("Partition"), disk, &part, uiquery))
+                	goto error;
+        if (!_partition_warn_busy (part))
+                goto error;
+        if (part->type == PED_PARTITION_EXTENDED) {
+                ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+                        _("Can't move an extended partition."));
+                goto error;
+        }
+        old_geom = part->geom;
+        fs = ped_file_system_open (&old_geom);
+        if (!fs)
+                goto error;
+
+        /* get new target */
+        if (!get_sector (_("Start?"), disk->dev, &start, &range_start, custom, uiquery))
+                goto error_close_fs;
+        end = start + old_geom.length - 1;
+        if (!get_sector (_("End?"), disk->dev, &end, &range_end, custom, uiquery))
+                goto error_close_fs;
+
+        /* set / test on "disk" */
+        if (!ped_geometry_init (&new_geom, disk->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, disk->dev),
+                        constraint_from_start_end (disk->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, uiquery->timer);
+        if (!fs_copy)
+                goto error_close_fs;
+        ped_file_system_close (fs_copy);
+        ped_file_system_close (fs);
+        if (!ped_disk_commit (disk)) {
+		//if (uiquery->need_commit) uiquery->need_commit = -1;
+                goto error;
+	}
+	uiquery->need_commit = 0;
+        if (range_start != NULL)
+                ped_geometry_destroy (range_start);
+        if (range_end != NULL)
+                ped_geometry_destroy (range_end);
+        return 1;
+
+error_destroy_constraint:
+        ped_constraint_destroy (constraint);
+error_close_fs:
+        ped_file_system_close (fs);
+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 (PedDisk* disk, PedPartition* part, char *name, UICalls *uiquery)
+{
+
+        if (!disk)
+                goto error;
+	if (!part) 
+        	if (!get_partition (_("Partition number?"), disk, &part, uiquery))
+                	goto error;
+	if (!name) {
+		strcpy(name, ped_partition_get_name(part));
+        	if (!uiquery->getstring(_("Partition name"), &name, NULL, NULL, 0))
+			goto error;
+	}
+
+        if (!name)
+                goto error;
+        if (!ped_partition_set_name (part, name))
+                goto error_free_name;
+        free (name);
+
+        /*if (!ped_disk_commit (disk))
+                goto error_destroy_disk;*/
+	uiquery->need_commit = 1;
+        return 1;
+
+error_free_name:
+        free (name);
+error:
+        return 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, UICalls *uiquery)
+{
+        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;
+        }
+
+        ped_partition_set_system (part, fs_type);
+        ped_disk_commit (part->disk);
+	uiquery->need_commit = 0;
+        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, UICalls *uiquery)
+{
+        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 (uiquery->timer);
+        ped_timer_set_state_name (uiquery->timer, _("searching for file systems"));
+        for (start = start_range->start; start <= start_range->end; start++) {
+                ped_timer_update (uiquery->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, uiquery)) {
+                        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 (uiquery->timer, 1.0);
+
+        return 1;
+
+error_remove_partition:
+        ped_disk_remove_partition (disk, part);
+error_partition_destroy:
+        ped_partition_destroy (part);
+error_constraint_done:
+        ped_constraint_done (&constraint);
+error:
+        return 0;
+}
+
+int
+do_rescue (PedDisk* disk, PedSector start, PedSector end, int custom, int warn, UICalls *uiquery)
+{
+
+        PedSector               fuzz;
+        PedGeometry             probe_start_region;
+        PedGeometry             probe_end_region;
+
+
+        if (!disk)
+                goto error;
+	if (warn)
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
+
+        if (!get_sector (_("Start"), disk->dev, &start, NULL, custom, uiquery))
+                goto error;
+        if (!get_sector (_("End"), disk->dev, &end, NULL, custom, uiquery))
+                goto error;
+
+        fuzz = PED_MAX (PED_MIN ((end - start) / 10, MEGABYTE_SECTORS(disk->dev)),
+                        MEGABYTE_SECTORS(disk->dev) * 16);
+
+        ped_geometry_init (&probe_start_region, disk->dev,
+                           PED_MAX(start - fuzz, 0),
+                           PED_MIN(2 * fuzz, (disk->dev)->length - (start - fuzz)));
+        ped_geometry_init (&probe_end_region, disk->dev,
+                           PED_MAX(end - fuzz, 0),
+                           PED_MIN(2 * fuzz, (disk->dev)->length - (end - fuzz)));
+
+        if (!_rescue_pass (disk, &probe_start_region, &probe_end_region, uiquery))
+                goto error;
+
+
+        return 1;
+
+
+error:
+        return 0;
+}
+
+int
+do_resize (PedDisk *disk, PedPartition *part, PedSector start, PedSector end, 
+						int custom, int warn, UICalls *uiquery)
+{
+
+        PedFileSystem           *fs;
+        PedConstraint           *constraint;
+        PedGeometry             *range_start = NULL, *range_end = NULL;
+        PedGeometry             new_geom;
+
+
+        if (!disk)
+                goto error;
+	if (warn)
+		if (!ask_boolean_question 
+		(_("WARNING: This writes all data to disk automatically, continue"),uiquery)) 
+			return 1;
+	if (!part) 
+        	if (!get_partition (_("Partition"), disk, &part, uiquery))
+                	goto error;
+        if (part->type != PED_PARTITION_EXTENDED) {
+                if (!_partition_warn_busy (part))
+                        goto error;
+        }
+
+        start = part->geom.start;
+        end = part->geom.end;
+        if (!get_sector (_("Start"), disk->dev, &start, &range_start, custom, uiquery))
+                goto error;
+        if (!get_sector (_("End"), disk->dev, &end, &range_end, custom, uiquery))
+                goto error;
+
+        if (!ped_geometry_init (&new_geom, disk->dev, start, end - start + 1))
+                goto error;
+        snap_to_boundaries (&new_geom, &part->geom, disk,
+                            range_start, range_end);
+
+        if (part->type == PED_PARTITION_EXTENDED) {
+                constraint = constraint_from_start_end (disk->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;
+                constraint = constraint_intersect_and_destroy (
+                                ped_file_system_get_resize_constraint (fs),
+                                constraint_from_start_end (
+                                        disk->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, uiquery->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);
+	uiquery->need_commit = 0;
+        ped_constraint_destroy (constraint);
+        if (range_start != NULL)
+                ped_geometry_destroy (range_start);
+        if (range_end != NULL)
+                ped_geometry_destroy (range_end);
+        return 1;
+
+error_close_fs:
+        ped_file_system_close (fs);
+error_destroy_constraint:
+        ped_constraint_destroy (constraint);
+error:
+        if (range_start != NULL)
+                ped_geometry_destroy (range_start);
+        if (range_end != NULL)
+                ped_geometry_destroy (range_end);
+        return 0;
+}
+
+int
+do_rm (PedDisk* disk, PedPartition* part, UICalls *uiquery)
+{
+       
+
+  
+        if (!disk)
+                goto error;
+	if (!part) 
+        	if (!get_partition (_("Partition number?"), disk, &part, uiquery))
+                	goto error;
+        if (!_partition_warn_busy (part))
+                goto error;
+
+        ped_disk_delete_partition (disk, part);
+        uiquery->need_commit = 1;
+        return 1;
+
+
+error:
+        return 0;
+}
 	int (*getdisktype)(const char*, PedDiskType**);
 	int (*getfstype)(const char*, PedFileSystemType**);
 	PedTimer* timer;
+	int need_commit;
 };
 
 extern int do_check (PedDisk*, PedPartition*, UICalls *);
-extern int do_cp (PedDisk*, PedPartition*, UICalls *);
+extern int do_cp (PedDisk*, PedPartition*, int warn, UICalls *);
+extern int do_mklabel (PedDevice*, PedDisk**, const PedDiskType*, UICalls *);
+extern int do_mkfs (PedDisk*, PedPartition*, const PedFileSystemType*, int warn, UICalls *);
+extern int do_mkpart (PedDisk*, PedSector start, PedSector end, int custom, PedPartitionType,
+	const PedFileSystemType*, PedPartition **newpart, UICalls *);
+extern int do_mkpartfs (PedDisk*, PedSector start, PedSector end, int custom, PedPartitionType,
+	const PedFileSystemType*, PedPartition **newpart, int warn, UICalls *);
 
 
 #endif
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.