nparted/nparted.c
joachimschmidt557 2c61b6ba6c Initial files
2019-02-26 13:01:51 +01:00

597 lines
14 KiB
C

/*
parted - a frontend to libparted
Copyright (C) 1999-2000 Andrew Clausen, Lennert Buytenhek and Red Hat, Inc.
Andrew Clausen <clausen@gnu.org>
Lennert Buytenhek <buytenh@gnu.org>
Matt Wilson, Red Hat Inc. <msw@redhat.com>
Modificated for Mario Teijeiro Otero <asimovi@teleline.es> 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 <nparted.h>
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;
}