diff --git parted-clean/configure parted-workdir/configure
index 7b7b1fd..7f6404f 100755
--- parted-clean/configure
+++ parted-workdir/configure
@@ -5323,6 +5323,7 @@ case "$host_os" in
linux*|uclinux*) OS=linux ;;
gnu*) OS=gnu ;;
beos*) OS=beos ;;
+ astral*) OS=astral ;;
*) as_fn_error $? "Unknown or unsupported OS \"$host_os\". Only \"linux\", \"uclinux\", \"gnu\" and \"beos\" are supported in this version of GNU Parted." "$LINENO" 5 ;;
esac
diff --git parted-workdir/libparted/arch/astral.c parted-workdir/libparted/arch/astral.c
new file mode 100644
index 0000000..4fda5e7
--- /dev/null
+++ parted-workdir/libparted/arch/astral.c
@@ -0,0 +1,564 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 2006-2007, 2009-2014, 2019-2023 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 3 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, see .
+*/
+
+#include
+
+#include
+#include
+
+/* POSIX headers */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../architecture.h"
+
+#define _(str) (str)
+
+#define ASTRAL_SPECIFIC(dev) ((struct astral_specific *) (dev)->arch_specific)
+
+struct astral_specific {
+ int fd;
+};
+
+#define BLOCK_TYPE_DISK 0
+#define BLOCK_TYPE_PART 1
+
+#define BLOCK_IOCTL_GETDESC 0xb10ccd35c
+
+struct astral_blockdesc {
+ void *filler;
+ int type;
+ uintmax_t lbaoffset;
+ size_t blockcapacity;
+ size_t blocksize;
+ void *filler2[2];
+};
+
+static int
+_do_fsync (PedDevice* dev)
+{
+ struct astral_specific* arch_specific = ASTRAL_SPECIFIC (dev);
+ int status;
+ PedExceptionOption ex_status;
+
+ while (1) {
+ status = fsync (arch_specific->fd);
+ if (status >= 0) break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ /* FALLTHROUGH */
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ default:
+ PED_ASSERT (0);
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+_device_init_blkdev(PedDevice* dev)
+{
+ int type;
+ struct astral_blockdesc desc;
+ int fd = open(dev->path, O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ if (ioctl(fd, BLOCK_IOCTL_GETDESC, &desc) < 0)
+ goto error;
+
+ close (fd);
+
+ dev->length = desc.blockcapacity;
+ dev->sector_size = dev->phys_sector_size = desc.blocksize;
+
+ /* XXX: We have no way to get this! */
+ dev->bios_geom.sectors = 63;
+ dev->bios_geom.heads = 255;
+ int cyl_size = dev->bios_geom.sectors * dev->bios_geom.heads;
+ dev->bios_geom.cylinders = dev->length / cyl_size
+ * (dev->sector_size / PED_SECTOR_SIZE_DEFAULT);
+ dev->hw_geom = dev->bios_geom;
+ dev->model = strdup("Disk device");
+
+ // determine type
+
+ if (dev->path && strstr(dev->path, "nvme"))
+ return PED_DEVICE_NVME;
+
+ if (dev->path && strstr(dev->path, "vioblk"))
+ return PED_DEVICE_VIRTBLK;
+
+ if (dev->path && strstr(dev->path, "ahci"))
+ return PED_DEVICE_SCSI;
+
+ return PED_DEVICE_UNKNOWN;
+error:
+ close(fd);
+ return 0;
+}
+
+static int
+_device_init_file(PedDevice* dev, struct stat* dev_statp)
+{
+ if (!dev_statp->st_size)
+ return 0;
+
+ dev->sector_size =
+ dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
+
+ dev->length = dev_statp->st_size / PED_SECTOR_SIZE_DEFAULT;
+
+ dev->bios_geom.cylinders = dev->length / (4 * 32);
+ dev->bios_geom.heads = 4;
+ dev->bios_geom.sectors = 32;
+ dev->hw_geom = dev->bios_geom;
+
+ dev->model = strdup(_("Disk Image"));
+
+ return PED_DEVICE_FILE;
+}
+
+static int
+_device_init(PedDevice* dev)
+{
+ struct stat dev_stat;
+ int type = 0;
+
+ /* Check if we're a regular file */
+ if (stat(dev->path, &dev_stat) < 0)
+ goto done;
+
+ if (S_ISBLK(dev_stat.st_mode))
+ type = _device_init_blkdev(dev);
+ else if (S_ISREG(dev_stat.st_mode))
+ type = _device_init_file(dev,&dev_stat);
+
+done:
+ return type;
+}
+
+
+static PedDevice*
+astral_new (const char* path)
+{
+ struct stat stat_info;
+ PedDevice* dev;
+
+ PED_ASSERT(path != NULL);
+
+ dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
+ if (!dev)
+ goto error;
+
+ dev->path = strdup(path);
+ if (!dev->path)
+ goto error_free_dev;
+
+ dev->arch_specific
+ = (struct astral_specific *) ped_malloc(sizeof(struct astral_specific));
+ if (dev->arch_specific == NULL)
+ goto error_free_path;
+
+ dev->open_count = 0;
+ dev->read_only = 0;
+ dev->external_mode = 0;
+ dev->dirty = 0;
+ dev->boot_dirty = 0;
+
+ if ((dev->type=_device_init(dev)) <= 0)
+ goto error_free_arch_specific;
+
+ /* All OK! */
+ return dev;
+
+error_free_arch_specific:
+ free (dev->arch_specific);
+
+error_free_path:
+ free (dev->path);
+
+error_free_dev:
+ free (dev);
+
+error:
+ return NULL;
+}
+
+static void
+astral_destroy (PedDevice* dev)
+{
+ free (dev->arch_specific);
+ free (dev->path);
+ free (dev->model);
+ free (dev);
+}
+
+static int
+astral_is_busy (PedDevice* dev)
+{
+ return 1;
+}
+
+static int
+astral_open (PedDevice* dev)
+{
+ struct astral_specific *arch_specific = ASTRAL_SPECIFIC(dev);
+
+retry:
+ arch_specific->fd = open(dev->path, O_RDWR);
+ if (arch_specific->fd == -1) {
+ char* rw_error_msg = strerror(errno);
+
+ arch_specific->fd = open (dev->path, O_RDONLY);
+ if (arch_specific->fd == -1) {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_CANCEL,
+ _("Error opening %s: %s"),
+ dev->path, strerror (errno))
+ != PED_EXCEPTION_RETRY) {
+ return 0;
+ } else {
+ goto retry;
+ }
+ } else {
+ ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_OK,
+ _("Unable to open %s read-write (%s). %s has "
+ "been opened read-only."),
+ dev->path, rw_error_msg, dev->path);
+ dev->read_only = 1;
+ }
+ } else {
+ dev->read_only = 0;
+ }
+
+ _do_fsync (dev);
+
+ return 1;
+}
+
+static int astral_refresh_open (PedDevice* dev)
+{
+ return 1;
+}
+
+static int astral_close (PedDevice* dev)
+{
+ struct astral_specific *arch_specific = ASTRAL_SPECIFIC(dev);
+
+ if (dev->dirty)
+ _do_fsync(dev);
+
+ close (arch_specific->fd);
+
+ return 1;
+}
+
+static int astral_refresh_close (PedDevice* dev)
+{
+ if (dev->dirty)
+ _do_fsync(dev);
+
+ return 1;
+}
+
+static int astral_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+ struct astral_specific *arch_specific = ASTRAL_SPECIFIC(dev);
+ int status;
+ PedExceptionOption ex_status;
+ size_t read_length = count * dev->sector_size;
+
+ PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
+
+ /* First, try to seek */
+ while(1)
+ {
+ if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
+ == start * dev->sector_size)
+ break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during seek for read on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status)
+ {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+ case PED_EXCEPTION_RETRY:
+ break /* out of switch */;
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+ /* If we seeked ok, now is the time to read */
+ while (1)
+ {
+ status = read(arch_specific->fd, buffer, read_length);
+ if (status == count * dev->sector_size)
+ break;
+
+ if (status > 0)
+ {
+ read_length -= status;
+ buffer += status;
+ continue;
+ }
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during read on %s"),
+ strerror (errno),
+ dev->path);
+
+ switch (ex_status)
+ {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+ case PED_EXCEPTION_RETRY:
+ break;
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int astral_write (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count)
+{
+ struct astral_specific *arch_specific = ASTRAL_SPECIFIC(dev);
+ int status;
+ PedExceptionOption ex_status;
+ size_t write_length = count * dev->sector_size;
+
+ PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
+
+ if (dev->read_only)
+ {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Can't write to %s, because it is opened read-only."),
+ dev->path)
+ != PED_EXCEPTION_IGNORE)
+ return 0;
+ else
+ return 1;
+ }
+
+ while(1)
+ {
+ if (lseek(arch_specific->fd,start * dev->sector_size,SEEK_SET)
+ == start * dev->sector_size)
+ break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during seek for write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status)
+ {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+ case PED_EXCEPTION_RETRY:
+ break;
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+#ifdef READ_ONLY
+ printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
+ dev->path, buffer, (int) start, (int) count);
+#else
+ dev->dirty = 1;
+ while(1)
+ {
+ status = write (arch_specific->fd, buffer, write_length);
+ if (status == count * dev->sector_size)
+ break;
+
+ if (status > 0)
+ {
+ write_length -= status;
+ buffer += status;
+ continue;
+ }
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status)
+ {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+ case PED_EXCEPTION_RETRY:
+ break;
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+#endif /* !READ_ONLY */
+
+ return 1;
+}
+
+static PedSector astral_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+ struct astral_specific* arch_specific = ASTRAL_SPECIFIC(dev);
+ PedSector done = 0;
+ int status;
+
+ PED_ASSERT(dev != NULL);
+
+ if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
+ != start * dev->sector_size)
+ return 0;
+
+ for (done = 0; done < count; done += status / dev->sector_size)
+ {
+ status = read (arch_specific->fd, buffer,
+ (size_t) ((count-done) * dev->sector_size));
+ if (status < 0)
+ break;
+ }
+
+ return done;
+}
+
+static int astral_sync (PedDevice* dev)
+{
+ if (dev->read_only)
+ return 1;
+ if (!_do_fsync (dev))
+ return 0;
+
+ return 1;
+}
+
+/* Probe for all available disks */
+static void astral_probe_all(void) {
+ DIR *dir = opendir("/dev/");
+ if (!dir)
+ return;
+
+ struct dirent *dent = readdir(dir);
+ struct stat stat;
+ while (dent) {
+ char full_path[100];
+ snprintf(full_path, 100, "/dev/%s", dent->d_name);
+ if (stat(full_path, &stat) == 0 && S_ISBLK(stat.st_mode) && major(stat.st_rdev) == 7) {
+ // figure out if this is a disk
+ int f = open(full_path, O_RDONLY);
+ struct astral_blockdesc desc = {0};
+ if (ioctl(f, BLOCK_IOCTL_GETDESC, &desc) == 0 && desc.type == BLOCK_TYPE_DISK)
+ _ped_device_probe(full_path);
+ }
+
+ dent = readdir(dir);
+ }
+
+ closedir(dir);
+}
+
+static char* astral_partition_get_path (const PedPartition* part)
+{
+ return NULL;
+}
+
+static int astral_partition_is_busy (const PedPartition* part)
+{
+ return 0;
+}
+
+static int astral_disk_commit (PedDisk* disk)
+{
+ return 0;
+}
+
+static PedDeviceArchOps astral_dev_ops = {
+ _new: astral_new,
+ destroy: astral_destroy,
+ is_busy: astral_is_busy,
+ open: astral_open,
+ refresh_open: astral_refresh_open,
+ close: astral_close,
+ refresh_close: astral_refresh_close,
+ read: astral_read,
+ write: astral_write,
+ check: astral_check,
+ sync: astral_sync,
+ sync_fast: astral_sync,
+ probe_all: astral_probe_all
+};
+
+static PedDiskArchOps astral_disk_ops = {
+ partition_get_path: astral_partition_get_path,
+ partition_is_busy: astral_partition_is_busy,
+ disk_commit: astral_disk_commit
+};
+
+PedArchitecture ped_astral_arch = {
+ dev_ops: &astral_dev_ops,
+ disk_ops: &astral_disk_ops
+};
diff --git parted-clean/libparted/architecture.c parted-workdir/libparted/architecture.c
index 4020f98..0126e39 100644
--- parted-clean/libparted/architecture.c
+++ parted-workdir/libparted/architecture.c
@@ -34,6 +34,9 @@ ped_set_architecture ()
#elif defined(__BEOS__)
extern PedArchitecture ped_beos_arch;
const PedArchitecture* arch = &ped_beos_arch;
+#elif defined(__astral__)
+ extern PedArchitecture ped_astral_arch;
+ const PedArchitecture* arch = &ped_astral_arch;
#else
extern PedArchitecture ped_gnu_arch;
const PedArchitecture* arch = &ped_gnu_arch;
diff --git parted-clean/libparted/libparted.c parted-workdir/libparted/libparted.c
index 204ce00..1b72255 100644
--- parted-clean/libparted/libparted.c
+++ parted-workdir/libparted/libparted.c
@@ -76,7 +76,6 @@ extern void ped_disk_pc98_init ();
extern void ped_disk_sun_init ();
extern void ped_disk_amiga_init ();
extern void ped_disk_dasd_init ();
-extern void ped_disk_atari_init ();
static void
init_disk_types ()
@@ -87,7 +86,6 @@ init_disk_types ()
#if defined __s390__ || defined __s390x__
ped_disk_dasd_init();
#endif
- ped_disk_atari_init (); /* easy false positives, so probe others first */
ped_disk_sun_init ();
#ifdef ENABLE_PC98
ped_disk_pc98_init ();
@@ -146,7 +144,6 @@ extern void ped_disk_pc98_done ();
extern void ped_disk_sun_done ();
extern void ped_disk_amiga_done ();
extern void ped_disk_dasd_done ();
-extern void ped_disk_atari_done ();
static void
done_disk_types ()
@@ -166,7 +163,6 @@ done_disk_types ()
ped_disk_bsd_done ();
ped_disk_amiga_done ();
ped_disk_aix_done ();
- ped_disk_atari_done ();
}
static void _init() __attribute__ ((constructor));
diff --git parted-clean/libparted/unit.c parted-workdir/libparted/unit.c
index a63b98d..01f46fb 100644
--- parted-clean/libparted/unit.c
+++ parted-workdir/libparted/unit.c
@@ -248,7 +248,7 @@ ped_unit_format_custom_byte (const PedDevice* dev, PedSector byte, PedUnit unit)
(w < 100.) ? 1 :
0 ;
-#ifdef __BEOS__
+#if defined(__BEOS__) || defined(__astral__)
snprintf (buf, 100, "%.*f%s", p, d, ped_unit_get_name(unit));
#else
snprintf (buf, 100, "%1$.*2$f%3$s", d, p, ped_unit_get_name (unit));