/* parted - a frontend to libparted Copyright (C) 1999-2000 Andrew Clausen, Lennert Buytenhek and Red Hat, Inc. Andrew Clausen Lennert Buytenhek Matt Wilson, Red Hat Inc. Modificated for Mario Teijeiro Otero for nparted This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include int do_check (PedDevice** dev, int npart) { PedDisk* disk; PedFileSystem* fs; PedPartition* part; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } fs = ped_file_system_open (&part->geom); if (!fs) goto error_close_disk; ped_file_system_check (fs); ped_file_system_close (fs); ped_disk_close (disk); return 1; error_close_disk: ped_disk_close (disk); error: return 0; } int do_cp (PedDevice** dev,int npart_src, char* dev_dest,int npart_dest) { PedDisk* src_disk = NULL; PedDisk* dst_disk = NULL; PedDevice* dst_device; PedPartition* src = NULL; PedPartition* dst = NULL; PedFileSystem* src_fs = NULL; src_disk = ped_disk_open (*dev); if (!src_disk) goto error; /* figure out source partition */ src = ped_disk_get_partition (src_disk, npart_src); if (!src) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Source partition doesn't exist.")); goto error_close_disk; } if (src->type == PED_PARTITION_EXTENDED) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Can't copy extended partitions.")); goto error_close_disk; } /* figure out target partition */ dst_device = ped_device_get (dev_dest); if (!dst_device) goto error_close_disk; dst_disk = ped_disk_open (dst_device); dst = ped_disk_get_partition (dst_disk, npart_dest); if (!dst) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Destination partition doesn't exist.")); goto error_close_disk; } if (ped_partition_is_busy (dst)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Destination partition is being used.")) != PED_EXCEPTION_IGNORE) goto error_close_disk; } dst->type = src->type; /* do the copy */ src_fs = ped_file_system_open (&src->geom); if (!src_fs) goto error_close_disk; if (!ped_file_system_copy (src_fs, &dst->geom)) goto error_close_fs; ped_file_system_close (src_fs); if (dst_disk && src_disk != dst_disk) ped_disk_close (dst_disk); ped_disk_close (src_disk); return 1; error_close_fs: ped_file_system_close (src_fs); error_close_disk: if (dst_disk && src_disk != dst_disk) ped_disk_close (dst_disk); ped_disk_close (src_disk); error: return 0; } int do_mklabel (PedDevice** dev,char *label) { PedDisk* disk; PedDiskType* type; ped_exception_fetch_all (); disk = ped_disk_open (*dev); if (!disk) ped_exception_catch (); ped_exception_leave_all (); if (disk) { if (ped_disk_is_busy (disk)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Partition(s) on %s are being used."), disk->dev->path) != PED_EXCEPTION_IGNORE) { ped_disk_close (disk); return 0; } } ped_disk_close (disk); } type = ped_disk_type_get (label); if (!type) goto error_syntax; ped_disk_create (*dev, type); return 1; error_syntax: return 0; } int do_mkfs (PedDevice** dev,int npart, char *fs_type) { PedDisk* disk; PedPartition* part; PedFileSystemType* type; PedFileSystem* fs; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (ped_partition_is_busy (part)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Partition is being used.")) != PED_EXCEPTION_IGNORE) goto error_close_disk; } if (!fs_type) goto error_close_disk; type = ped_file_system_type_get (fs_type); if (!type) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Unknown filesystem type.")); goto error_close_disk; } fs = ped_file_system_create (&part->geom, type); if (!fs) goto error; ped_file_system_close (fs); if (!ped_partition_set_system (part, type)) goto error_close_disk; if (!ped_disk_write (disk)) goto error_close_disk; ped_disk_close (disk); return 1; error_close_disk: ped_disk_close (disk); error: return 0; } int do_mkpart (PedDevice** dev,char ptype,char *ftype,PedSector start,PedSector end) { PedDisk* disk; PedPartition* part; PedPartitionType part_type; PedFileSystemType* fs_type; PedConstraint* constraint; disk = ped_disk_open (*dev); if (!disk) goto error; constraint = ped_constraint_any (disk); if (!constraint) goto error_close_disk; switch (ptype) { case 'p': part_type = PED_PARTITION_PRIMARY; break; case 'e': part_type = PED_PARTITION_EXTENDED; break; case 'l': part_type = PED_PARTITION_LOGICAL; break; default: goto error_destroy_constraint; } if (part_type == PED_PARTITION_EXTENDED) { fs_type = NULL; } else { if (!ftype) { goto error_destroy_constraint; } fs_type = ped_file_system_type_get (ftype); if (!fs_type) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Unknown file system type.")); goto error_destroy_constraint; } } part = ped_partition_new (disk, part_type, fs_type, start, end); if (!part) goto error_destroy_constraint; if (!ped_disk_add_partition (disk, part, constraint)) goto error_destroy_part; /* FIXME: ped_partition_new() doesn't probe the file system for * what type of partition should be created. So we do it here. * Question: SHOULD we probe the file system on * ped_partition_new()? It only makes sense if someone accidently * delete their partition... */ ped_partition_set_system (part, fs_type); ped_disk_write (disk); ped_constraint_destroy (constraint); ped_disk_close (disk); return 1; error_destroy_part: ped_partition_destroy (part); error_destroy_constraint: ped_constraint_destroy (constraint); error_close_disk: ped_disk_close (disk); error: return 0; } /* FIXME - this is a mess */ int do_mkpartfs (PedDevice** dev,char ptype,char *ftype,PedSector start, PedSector end) { PedDisk* disk; PedPartition* part; PedPartitionType part_type; PedFileSystemType* fs_type; PedFileSystem* fs; PedConstraint* constraint; disk = ped_disk_open (*dev); if (!disk) goto error; constraint = ped_constraint_any (disk); if (!constraint) goto error_close_disk; switch (ptype) { case 'p': part_type = PED_PARTITION_PRIMARY; break; case 'l': part_type = PED_PARTITION_LOGICAL; break; case 'e': default: goto error_destroy_constraint; } if (part_type == PED_PARTITION_EXTENDED) { fs_type = NULL; } else { if (!ftype) { goto error_destroy_constraint; } fs_type = ped_file_system_type_get (ftype); if (!fs_type) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Unknown file system type.")); goto error_destroy_constraint; } } part = ped_partition_new (disk, part_type, fs_type, start, end); if (!part) goto error_destroy_constraint; if (!ped_disk_add_partition (disk, part, constraint)) goto error_destroy_part; fs = ped_file_system_create (&part->geom, fs_type); if (!fs) goto error_remove_part; ped_file_system_close (fs); /* set the system AGAIN, because if it's FAT16 or FAT32 (or whatever) will * be known now. */ ped_partition_set_system (part, fs_type); ped_disk_write (disk); ped_constraint_destroy (constraint); ped_disk_close (disk); return 1; error_remove_part: ped_disk_delete_partition (disk, part); goto error_close_disk; error_destroy_part: ped_partition_destroy (part); error_destroy_constraint: ped_constraint_destroy (constraint); error_close_disk: ped_disk_close (disk); error: return 0; } int do_move (PedDevice** dev,int part_src,PedSector start, PedSector end) { PedDisk* disk = NULL; PedPartition* part = NULL; PedGeometry old_geom; PedConstraint* constraint; PedFileSystem* fs = NULL; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, part_src); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (part->type == PED_PARTITION_EXTENDED) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Can't move extended partitions.")); goto error_close_disk; } if (ped_partition_is_busy (part)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Partition is being used.")) != PED_EXCEPTION_IGNORE) goto error_close_disk; } /* NOTE: this gets aligned by ped_disk_set_partition_geom() */ old_geom = part->geom; constraint = ped_constraint_any (disk); if (!constraint) goto error_close_disk; if (!ped_disk_set_partition_geom (disk, part, constraint, start, end)) { ped_constraint_destroy (constraint); goto error_close_disk; } 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_disk; } /* do the move */ fs = ped_file_system_open (&old_geom); if (!fs) goto error_close_disk; if (!ped_file_system_copy (fs, &part->geom)) goto error_close_fs; ped_file_system_close (fs); if (!ped_disk_write (disk)) goto error_close_disk; ped_disk_close (disk); return 1; error_close_fs: ped_file_system_close (fs); error_close_disk: ped_disk_close (disk); error: return 0; } int do_name (PedDevice** dev, int npart,char *name) { PedDisk* disk; PedPartition* part; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (!name) { goto error_close_disk; } if (!ped_partition_set_name (part, name)) goto error_close_disk; if (!ped_disk_write (disk)) goto error_close_disk; ped_disk_close (disk); return 1; error_close_disk: ped_disk_close (disk); error: return 0; } int do_resize (PedDevice** dev,int npart, PedSector start, PedSector end) { PedDisk* disk; PedPartition* part; PedFileSystem* fs; PedFileSystemType* fs_type; PedConstraint* constraint; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (ped_partition_is_busy (part)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Partition is being used.")) != PED_EXCEPTION_IGNORE) goto error_close_disk; } if (part->type == PED_PARTITION_EXTENDED) { constraint = ped_constraint_any (disk); if (!ped_disk_set_partition_geom (disk, part, constraint, start, end)) goto error_destroy_constraint; ped_partition_set_system (part, NULL); } else { fs = ped_file_system_open (&part->geom); if (!fs) goto error_close_disk; fs_type = fs->type; constraint = ped_file_system_get_resize_constraint (fs); if (!ped_disk_set_partition_geom (disk, part, constraint, start, end)) goto error_close_fs; if (!ped_file_system_resize (fs, &part->geom)) goto error_close_fs; ped_file_system_close (fs); ped_partition_set_system (part, fs_type); } ped_disk_write (disk); ped_constraint_destroy (constraint); ped_disk_close (disk); return 1; error_close_fs: ped_file_system_close (fs); error_destroy_constraint: ped_constraint_destroy (constraint); error_close_disk: ped_disk_close (disk); error: return 0; } int do_rm (PedDevice** dev, int npart) { PedDisk* disk; PedPartition* part; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (ped_partition_is_busy (part)) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, _("Partition is being used.")) != PED_EXCEPTION_IGNORE) goto error_close_disk; } ped_disk_delete_partition (disk, part); ped_disk_write (disk); ped_disk_close (disk); return 1; error_close_disk: ped_disk_close (disk); error: return 0; } int do_set (PedDevice** dev, int npart, char *flag_name,int state) { PedDisk* disk; PedPartition* part; PedPartitionFlag flag; disk = ped_disk_open (*dev); if (!disk) goto error; part = ped_disk_get_partition (disk, npart); if (!part) { ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, _("Partition doesn't exist.")); goto error_close_disk; } if (!flag_name) goto error_help; flag = ped_partition_flag_get_by_name (flag_name); if (!flag) goto error_help; if (!ped_partition_set_flag (part, flag, state)) goto error_close_disk; if (!ped_disk_write (disk)) goto error_close_disk; ped_disk_close (disk); return 1; error_help: error_close_disk: ped_disk_close (disk); error: return 0; }