diff -urN parted-1.4.7.orig/include/parted/Makefile.am parted-1.4.7/include/parted/Makefile.am --- parted-1.4.7.orig/include/parted/Makefile.am Mon Dec 4 14:12:47 2000 +++ parted-1.4.7/include/parted/Makefile.am Tue Jan 16 22:37:22 2001 @@ -13,5 +13,6 @@ disk_loop.h \ disk_mac.h \ disk_pc98.h \ + disk_sun.h \ endian.h diff -urN parted-1.4.7.orig/include/parted/disk_sun.h parted-1.4.7/include/parted/disk_sun.h --- parted-1.4.7.orig/include/parted/disk_sun.h Wed Dec 31 19:00:00 1969 +++ parted-1.4.7/include/parted/disk_sun.h Thu Jan 18 10:41:47 2001 @@ -0,0 +1,41 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + + libparted - a library for manipulating disk partitions + Copyright (C) 1998-2000 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 + (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 + + Contributor: Ben Collins +*/ + +#ifndef PED_DISK_SUN_H_INCLUDED +#define PED_DISK_SUN_H_INCLUDED + +typedef struct { + u_int8_t type; +} SUNPartitionData; + +typedef struct { + PedSector block_size; + PedSector length; +} SUNDiskData; + +#define SUN_NAME "sun" + +extern void ped_disk_sun_init (); +extern void ped_disk_sun_done (); + +#endif /* PED_DISK_SUN_H_INCLUDED */ + diff -urN parted-1.4.7.orig/libparted/Makefile.am parted-1.4.7/libparted/Makefile.am --- parted-1.4.7.orig/libparted/Makefile.am Thu Jan 18 12:09:19 2001 +++ parted-1.4.7/libparted/Makefile.am Tue Jan 16 22:38:22 2001 @@ -22,7 +22,8 @@ disk_dos.c \ disk_loop.c \ disk_mac.c \ - disk_pc98.c + disk_pc98.c \ + disk_sun.c libparted_la_LIBADD = fs_ext2/libext2.la \ fs_fat/libfat.la \ diff -urN parted-1.4.7.orig/libparted/disk_sun.c parted-1.4.7/libparted/disk_sun.c --- parted-1.4.7.orig/libparted/disk_sun.c Wed Dec 31 19:00:00 1969 +++ parted-1.4.7/libparted/disk_sun.c Thu Jan 18 11:59:05 2001 @@ -0,0 +1,679 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + + libparted - a library for manipulating disk partitions + Copyright (C) 1998-2000 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 + (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 + + Contributor: Ben Collins +*/ + +#include "config.h" + +#include + +#include +#include +#include + +#include +#if ENABLE_NLS +# define _(String) dgettext (PACKAGE, String) +#else +# define _(String) (String) +#endif /* ENABLE_NLS */ + +/* Most of this came from util-linux's sun support, which was mostly done + by Jakub Jelinek. */ + +#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */ +#define SUN_DISK_MAXPARTITIONS 8 + +#define WHOLE_DISK_ID 5 +#define WHOLE_DISK_PART 2 /* as in 0, 1, 2 (3rd partition) */ + +typedef struct { + u_int32_t start_cylinder; /* where the part starts... */ + u_int32_t num_sectors; /* ...and it's length */ +} __attribute__ ((packed)) SUNRawPartition; + +typedef struct { + u_int8_t spare1; + u_int8_t id; /* Partition type */ + u_int8_t spare2; + u_int8_t flags; /* Partition flags */ +} __attribute__ ((packed)) SUNPartitionInfo; + +typedef struct { + u_int8_t info[128]; /* Informative text string */ + u_int8_t spare0[14]; + SUNPartitionInfo infos[SUN_DISK_MAXPARTITIONS]; + u_int8_t spare1[246]; /* Boot information etc. */ + u_int16_t rspeed; /* Disk rotational speed */ + u_int16_t pcylcount; /* Physical cylinder count */ + u_int16_t sparecyl; /* extra sects per cylinder */ + u_int8_t spare2[4]; /* More magic... */ + u_int16_t ilfact; /* Interleave factor */ + u_int16_t ncyl; /* Data cylinder count */ + u_int16_t nacyl; /* Alt. cylinder count */ + u_int16_t ntrks; /* Tracks per cylinder */ + u_int16_t nsect; /* Sectors per track */ + u_int8_t spare3[4]; /* Even more magic... */ + SUNRawPartition partitions[SUN_DISK_MAXPARTITIONS]; + u_int16_t magic; /* Magic number */ + u_int16_t csum; /* Label xor'd checksum */ +} __attribute__ ((packed)) SUNRawLabel; + +static int sun_probe (const PedDevice *dev); +static PedDisk* sun_open (PedDevice* dev); +static PedDisk* sun_create (PedDevice* dev); +static int sun_clobber (PedDevice* dev); +static int sun_close (PedDisk* disk); +static int sun_read (PedDisk* disk); +static int sun_write (PedDisk* disk); + +static PedPartition* sun_partition_new ( + const PedDisk* disk, PedPartitionType part_type, + const PedFileSystemType* fs_type, PedSector start, PedSector end); +static void sun_partition_destroy (PedPartition* part); +static int sun_partition_set_flag ( + PedPartition* part, PedPartitionFlag flag, int state); +static int sun_partition_get_flag ( + const PedPartition* part, PedPartitionFlag flag); +static int sun_partition_is_flag_available ( + const PedPartition* part, + PedPartitionFlag flag); +static int sun_partition_align (PedPartition* part, + const PedConstraint* constraint); +static int sun_partition_enumerate (PedPartition* part); +static int sun_get_max_primary_partition_count (const PedDisk* disk); + +static int sun_alloc_metadata (PedDisk* disk); + +static PedDiskOps sun_disk_ops = { + probe: sun_probe, + open: sun_open, + close: sun_close, + read: sun_read, + write: sun_write, + create: sun_create, + clobber: sun_clobber, + + partition_new: sun_partition_new, + partition_destroy: sun_partition_destroy, + partition_set_flag: sun_partition_set_flag, + partition_get_flag: sun_partition_get_flag, + partition_is_flag_available: sun_partition_is_flag_available, + partition_align: sun_partition_align, + partition_enumerate: sun_partition_enumerate, + alloc_metadata: sun_alloc_metadata, + get_max_primary_partition_count: + sun_get_max_primary_partition_count, + + partition_set_name: NULL, + partition_get_name: NULL, + partition_set_extended_system: NULL, +}; + +static PedDiskType sun_disk_type = { + next: NULL, + name: "sun", + ops: &sun_disk_ops, + features: 0 +}; + +void +ped_disk_sun_init () +{ + PED_ASSERT (sizeof (SUNRawLabel) == 512, return); + ped_register_disk_type (&sun_disk_type); +} + +void +ped_disk_sun_done () +{ + ped_unregister_disk_type (&sun_disk_type); +} + +/* Checksum computation */ +static void +sun_compute_checksum (SUNRawLabel *label) +{ + u_int16_t *ush = (u_int16_t *)label; + u_int16_t csum = 0; + + while(ush < (u_int16_t *)(&label->csum)) + csum ^= *ush++; + label->csum = csum; +} + +/* Checksum Verification */ +static int +sun_verify_checksum (SUNRawLabel *label) +{ + u_int16_t *ush = ((u_int16_t *)(label + 1)) - 1; + u_int16_t csum = 0; + + while (ush >= (u_int16_t *)label) + csum ^= *ush--; + + return !csum; +} + +static PedDisk* +sun_alloc (PedDevice* dev) +{ + PedDisk* disk; + + PED_ASSERT (dev != NULL, return NULL); + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + if (dev->length < 512) { + ped_exception_throw ( + PED_EXCEPTION_ERROR, + PED_EXCEPTION_CANCEL, + _("%s is too small for a Sun disk label!"), + dev->path); + goto error_close_dev; + } + + disk = ped_disk_alloc (dev, &sun_disk_type); + if (!disk) + goto error_close_dev; + + disk->disk_specific = (SUNDiskData*) ped_malloc (sizeof (SUNDiskData)); + if (!disk->disk_specific) + goto error_free_disk; + return disk; + +error_free_disk: + ped_disk_free (disk); +error_close_dev: + ped_device_close ((PedDevice*) dev); +error: + return NULL; +} + +static int +sun_free (PedDisk *disk) +{ + ped_device_close (disk->dev); + ped_free (disk->disk_specific); + ped_disk_free (disk); + return 1; +} + +static int +sun_probe (const PedDevice *dev) +{ + PedDiskType* disk_type; + SUNRawLabel label; + int i; + + PED_ASSERT (dev != NULL, return 0); + + if (!ped_device_open ((PedDevice*) dev)) + return 0; + if (!ped_device_read (dev, &label, 0, 1)) { + ped_device_close ((PedDevice*) dev); + return 0; + } + + ped_device_close ((PedDevice*) dev); + + /* check magic */ + if (PED_BE16_TO_CPU (label.magic) != SUN_DISK_MAGIC) + return 0; + + if (!sun_verify_checksum(&label)) { + ped_exception_throw ( + PED_EXCEPTION_ERROR, + PED_EXCEPTION_CANCEL, + _("Corrupted Sun disk label detected.")); + return 0; + } + + return 1; +} + +static PedDisk* +sun_open (PedDevice* dev) +{ + PedDisk* disk; + + disk = sun_alloc(dev); + if (!disk) + goto error; + + if (!sun_read (disk)) + goto error_free_disk; + + return disk; + +error_free_disk: + sun_free (disk); +error: + return NULL; +} + +static int +sun_close (PedDisk* disk) +{ + PED_ASSERT (disk != NULL, return 0); + sun_free(disk); + return 1; +} + +static PedDisk* +sun_create (PedDevice* dev) +{ + SUNRawLabel label; + PedSector length; + SUNDiskData* disk_data; + + PED_ASSERT (dev != NULL, return 0); + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + + memset(&label, 0, sizeof(SUNRawLabel)); + + /* util-linux's fdisk asks about these...I'm just going to use + defaults since most people do anyway...sue me. */ + label.magic = PED_CPU_TO_BE16 (SUN_DISK_MAGIC); + label.nacyl = PED_CPU_TO_BE16 (2); + label.pcylcount = PED_CPU_TO_BE16 (dev->cylinders); + label.rspeed = PED_CPU_TO_BE16 (5400); + label.ilfact = PED_CPU_TO_BE16 (1); + label.sparecyl = PED_CPU_TO_BE16 (dev->sectors); + label.ntrks = PED_CPU_TO_BE16 (dev->heads); + label.nsect = PED_CPU_TO_BE16 (dev->sectors); + label.ncyl = PED_CPU_TO_BE16 (dev->cylinders - 2); + + /* Add a whole disk partition at a minimum */ + label.infos[WHOLE_DISK_PART].id = WHOLE_DISK_ID; + label.partitions[WHOLE_DISK_PART].start_cylinder = 0; + + disk_data->block_size = PED_BE16_TO_CPU(label.ntrks) * + PED_BE16_TO_CPU(label.nsect); + disk_data->length = disk_data->block_size * + PED_BE16_TO_CPU(label.ncyl); + + label.partitions[WHOLE_DISK_PART].num_sectors = + PED_CPU_TO_BE32(disk_data->length); + + /* Now a neato string to describe this label */ + snprintf(label.info, sizeof(label.info) - 1, + "GNU Parted Custom cyl %d alt 2 hd %d sec %d", + PED_BE16_TO_CPU(label.ncyl), PED_BE16_TO_CPU(label.ntrks), + PED_BE16_TO_CPU(label.nsect)); + + sun_compute_checksum(&label); + + if (!ped_device_write (dev, &label, 0, 1)) + goto error_close_dev; + if (!ped_device_sync (dev)) + goto error_close_dev; + ped_device_close (dev); + return sun_open (dev); + +error_close_dev: + ped_device_close (dev); +error: + return 0; +} + +static int +sun_clobber (PedDevice* dev) +{ + SUNRawLabel label; + + PED_ASSERT (dev != NULL, return 0); + PED_ASSERT (sun_probe (dev), return 0); + + if (!ped_device_open ((PedDevice*) dev)) + goto error; + if (!ped_device_read (dev, &label, 0, 1)) + goto error_close_dev; + + label.magic = 0; + + if (!ped_device_write (dev, &label, 0, 1)) + goto error_close_dev; + + ped_device_close (dev); + return 1; + +error_close_dev: + ped_device_close (dev); +error: + return 0; +} + +static int +sun_read (PedDisk* disk) +{ + SUNRawLabel label; + SUNPartitionData* sun_data; + SUNDiskData* disk_data; + int i, s; + PedPartition* part; + PedSector cyl_size, end, start; + PedConstraint* constraint_exact; + + PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (disk->dev != NULL, return 0); + PED_ASSERT (disk->disk_specific != NULL, return 0); + + ped_disk_delete_all (disk); + + if (!ped_device_open ((PedDevice*) disk->dev)) + goto error; + if (!ped_device_read (disk->dev, &label, 0, 1)) + goto error_close_dev; + + /* Unfortunately, this may not be the same as the physical + settings. So we use the label's values. */ + disk_data = disk->disk_specific; + disk_data->block_size = PED_BE16_TO_CPU(label.ntrks) * + PED_BE16_TO_CPU(label.nsect); + disk_data->length = disk_data->block_size * + PED_BE16_TO_CPU(label.ncyl); + + for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) { + if (PED_BE32_TO_CPU(label.partitions[i].num_sectors) + && label.infos[i].id + && label.infos[i].id != WHOLE_DISK_ID) { + start = PED_BE32_TO_CPU(label.partitions[i].start_cylinder) + * disk_data->block_size; + end = start + PED_BE32_TO_CPU(label.partitions[i].num_sectors) - 1; + + part = ped_partition_new (disk, PED_PARTITION_PRIMARY, NULL, + start, end); + if (!part) + goto error_close_dev; + + sun_data = part->disk_specific; + sun_data->type = PED_BE32_TO_CPU(label.infos[i].id); + + part->num = i + 1; + part->fs_type = ped_file_system_probe (&part->geom); + + constraint_exact = ped_constraint_exact (&part->geom); + if (!ped_disk_add_partition (disk, part, constraint_exact)) + goto error_close_dev; + ped_constraint_destroy (constraint_exact); + } + } + + ped_device_close ((PedDevice*) disk->dev); + return 1; + + error_close_dev: + ped_device_close ((PedDevice*) disk->dev); + error: + return 0; +} + +static int +sun_write (PedDisk* disk) +{ + SUNRawLabel label; + SUNPartitionData* sun_data; + SUNDiskData* disk_data; + PedPartition* part; + PedSector length; + int i; + + PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (disk->dev != NULL, return 0); + + if (!ped_device_read (disk->dev, &label, 0, 1)) + return 0; + + memset (label.partitions, 0, + sizeof (SUNRawPartition) * SUN_DISK_MAXPARTITIONS); + memset (label.infos, 0, + sizeof (SUNPartitionInfo) * SUN_DISK_MAXPARTITIONS); + + disk_data = disk->disk_specific; + + for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) { + part = ped_disk_get_partition (disk, i + 1); + + if (!part) { + if (i != WHOLE_DISK_PART) + continue; + + /* Ok, nothing explicitly in the whole disk + partition, so let's put it there for safety + sake. */ + + label.infos[i].id = WHOLE_DISK_ID; + label.partitions[i].start_cylinder = 0; + label.partitions[i].num_sectors = + PED_CPU_TO_BE32(disk_data->length); + continue; + } + + sun_data = part->disk_specific; + label.infos[i].id = sun_data->type; + length = part->geom.end - part->geom.start + 1; + label.partitions[i].start_cylinder + = PED_CPU_TO_BE32 (part->geom.start) / disk_data->block_size; + label.partitions[i].num_sectors + = PED_CPU_TO_BE32 (length); + } + + sun_compute_checksum(&label); + + if (!ped_device_write (disk->dev, &label, 0, 1)) + return 0; + if (!ped_device_sync (disk->dev)) + return 0; + + return 1; +} + +static PedPartition* +sun_partition_new (const PedDisk* disk, PedPartitionType part_type, + const PedFileSystemType* fs_type, + PedSector start, PedSector end) +{ + PedPartition* part; + SUNPartitionData* sun_data; + + part = ped_partition_alloc (disk, part_type, fs_type, start, end); + if (!part) + goto error; + + if (ped_partition_is_active (part)) { + part->disk_specific + = sun_data = ped_malloc (sizeof (SUNPartitionData)); + if (!sun_data) + goto error_free_part; + sun_data->type = 0; + } else { + part->disk_specific = NULL; + } + + return part; + +error_free_sun_data: + ped_free (sun_data); +error_free_part: + ped_free (part); +error: + return NULL; +} + + +static void +sun_partition_destroy (PedPartition* part) +{ + PED_ASSERT (part != NULL, return); + + if (ped_partition_is_active (part)) + ped_free (part->disk_specific); + ped_free (part); +} + + +static int +sun_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state) +{ + /* no flags for sun */ + return 0; +} + + +static int +sun_partition_get_flag (const PedPartition* part, PedPartitionFlag flag) +{ + /* no flags for sun */ + return 0; +} + + +static int +sun_partition_is_flag_available (const PedPartition* part, + PedPartitionFlag flag) +{ + /* no flags for sun */ + return 0; +} + + +static int +sun_get_max_primary_partition_count (const PedDisk* disk) +{ + return SUN_DISK_MAXPARTITIONS; +} + +static PedConstraint* +_primary_constraint (PedDisk* disk) +{ + PedAlignment start_align; + PedAlignment end_align; + PedGeometry max_geom; + SUNDiskData* disk_data = disk->disk_specific; + + if (!ped_alignment_init (&start_align, 0, disk_data->block_size)) + return NULL; + if (!ped_alignment_init (&end_align, -1, disk_data->block_size)) + return NULL; + if (!ped_geometry_init (&max_geom, disk, 0, disk_data->length)) + return NULL; + + return ped_constraint_new (&start_align, &end_align, &max_geom, + &max_geom, 1); +} + +/* argghh! this should be somewhere else... but where?! */ +static int +_try_constraint (PedPartition* part, const PedConstraint* external, + PedConstraint* internal) +{ + PedConstraint* intersection; + PedGeometry* solution; + + intersection = ped_constraint_intersect (external, internal); + ped_constraint_destroy (internal); + if (!intersection) + goto fail; + + solution = ped_constraint_solve_nearest (intersection, &part->geom); + if (!solution) + goto fail_free_intersection; + ped_geometry_set (&part->geom, solution->start, solution->length); + ped_geometry_destroy (solution); + ped_constraint_destroy (intersection); + return 1; + +fail_free_intersection: + ped_constraint_destroy (intersection); +fail: + return 0; +} + +static int +sun_partition_align (PedPartition* part, const PedConstraint* constraint) +{ + PED_ASSERT (part != NULL, return 0); + + if (!_try_constraint (part, constraint, + _primary_constraint (part->geom.disk))) { + ped_exception_throw ( + PED_EXCEPTION_ERROR, + PED_EXCEPTION_CANCEL, + _("Unable to align partition.")); + return 0; + } + + return 1; +} + +static int +sun_partition_enumerate (PedPartition* part) +{ + int i; + PedPartition* p; + + /* never change the partition numbers */ + if (part->num != -1) + return 1; + for (i = 1; i <= SUN_DISK_MAXPARTITIONS; i++) { + p = ped_disk_get_partition (part->geom.disk, i); + if (!p) { + part->num = i; + return 1; + } + } + + /* failed to allocate a number */ + ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, + _("Unable to allocate a sun disklabel slot")); + return 0; +} + +static int +sun_alloc_metadata (PedDisk* disk) +{ + PedPartition* new_part; + PedConstraint* constraint_any = ped_constraint_any (disk); + + PED_ASSERT (disk != NULL, goto error); + PED_ASSERT (disk->disk_specific != NULL, return 0); + PED_ASSERT (disk->dev != NULL, goto error); +#if 0 + /* allocate 1 sector for the disk label at the start */ + new_part = ped_partition_new (disk, + PED_PARTITION_PRIMARY | PED_PARTITION_METADATA, + NULL, 0, 0); + if (!new_part) + goto error; + + if (!ped_disk_add_partition (disk, new_part, constraint_any)) { + ped_partition_destroy (new_part); + goto error; + } +#endif + ped_constraint_destroy (constraint_any); + return 1; +error: + ped_constraint_destroy (constraint_any); + return 0; +} diff -urN parted-1.4.7.orig/libparted/fs_ext2/interface.c parted-1.4.7/libparted/fs_ext2/interface.c --- parted-1.4.7.orig/libparted/fs_ext2/interface.c Mon Dec 4 14:12:47 2000 +++ parted-1.4.7/libparted/fs_ext2/interface.c Tue Jan 16 22:40:33 2001 @@ -31,6 +31,7 @@ #include #include #include +#include #include "ext2.h" #include "parted_io.h" @@ -342,6 +343,12 @@ if (strcmp (disk_type->name, BSD_NAME) == 0) { BSDPartitionData* bsd_data = part->disk_specific; bsd_data->type = 0x8; + return 1; + } + + if (strcmp (disk_type->name, SUN_NAME) == 0) { + SUNPartitionData* sun_data = part->disk_specific; + sun_data->type = 0x83; return 1; } diff -urN parted-1.4.7.orig/libparted/fs_linux_swap/linux_swap.c parted-1.4.7/libparted/fs_linux_swap/linux_swap.c --- parted-1.4.7.orig/libparted/fs_linux_swap/linux_swap.c Fri Jan 5 08:31:23 2001 +++ parted-1.4.7/libparted/fs_linux_swap/linux_swap.c Tue Jan 16 22:41:41 2001 @@ -28,6 +28,7 @@ #include #include #include +#include #include #if ENABLE_NLS @@ -565,6 +566,12 @@ if (strcmp (disk_type->name, BSD_NAME) == 0) { BSDPartitionData* bsd_data = part->disk_specific; bsd_data->type = 0x1; + return 1; + } + + if (strcmp (disk_type->name, SUN_NAME) == 0) { + SUNPartitionData* sun_data = part->disk_specific; + sun_data->type = 0x82; return 1; } diff -urN parted-1.4.7.orig/libparted/libparted.c parted-1.4.7/libparted/libparted.c --- parted-1.4.7.orig/libparted/libparted.c Thu Jan 11 14:03:16 2001 +++ parted-1.4.7/libparted/libparted.c Tue Jan 16 22:38:51 2001 @@ -65,6 +65,7 @@ ped_disk_pc98_init (); ped_disk_mac_init (); ped_disk_bsd_init (); + ped_disk_sun_init (); } static void @@ -102,6 +103,7 @@ ped_disk_loop_done (); ped_disk_mac_done (); ped_disk_bsd_done (); + ped_disk_sun_done (); } static void