File 0007-hfs-Add-support-for-Linux-ioctl-calls.patch of Package hfsplus-tools
From fdb33ffc0bbf5914d5315cc44c8be9d50323692e Mon Sep 17 00:00:00 2001
From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Date: Fri, 23 Jun 2023 01:19:46 +0200
Subject: [PATCH 7/7] hfs: Add support for Linux ioctl() calls
---
fsck_hfs/dfalib/SDevice.c | 36 ++++++++++++++++++++++++++++++++++
fsck_hfs/dfalib/fsck_journal.c | 4 ++++
fsck_hfs/fsck_hfs.c | 15 ++++++++++++++
newfs_hfs/newfs_hfs.c | 29 +++++++++++++++++++++++++++
4 files changed, 84 insertions(+)
diff --git a/fsck_hfs/dfalib/SDevice.c b/fsck_hfs/dfalib/SDevice.c
index 358d3fb..319f661 100644
--- a/fsck_hfs/dfalib/SDevice.c
+++ b/fsck_hfs/dfalib/SDevice.c
@@ -45,7 +45,43 @@ OSErr GetDeviceSize(int driveRefNum, UInt64 *numBlocks, UInt32 *blockSize)
#if BSD
UInt64 devBlockCount = 0;
int devBlockSize = 0;
+#if LINUX
+ struct stat stbuf;
+
+ devBlockSize = 512;
+#ifndef BLKGETSIZE
+#define BLKGETSIZE _IO(0x12,96)
+#endif
+#ifndef BLKGETSIZE64
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#endif
+ if (fstat(driveRefNum, &stbuf) < 0){
+ printf("Error: %s\n", strerror(errno));
+ return(-1);
+ }
+
+ if (S_ISREG(stbuf.st_mode)) {
+ devBlockCount = stbuf.st_size / 512;
+ }
+ else if (S_ISBLK(stbuf.st_mode)) {
+ unsigned long size;
+ u_int64_t size64;
+ if (!ioctl(driveRefNum, BLKGETSIZE64, &size64))
+ devBlockCount = size64 / 512;
+ else if (!ioctl(driveRefNum, BLKGETSIZE, &size))
+ devBlockCount = size;
+ else{
+ printf("Error: %s\n", strerror(errno));
+ return(-1);
+ }
+
+ }
+ else{
+ printf("Device is not a block device");
+ return(-1);
+ }
+#elif BSD
if (ioctl(driveRefNum, DKIOCGETBLOCKCOUNT, &devBlockCount) < 0) {
if (debug) plog("ioctl(DKIOCGETBLOCKCOUNT) for fd %d: %s\n", driveRefNum, strerror(errno));
return (-1);
diff --git a/fsck_hfs/dfalib/fsck_journal.c b/fsck_hfs/dfalib/fsck_journal.c
index 4d5acc3..a038cb9 100644
--- a/fsck_hfs/dfalib/fsck_journal.c
+++ b/fsck_hfs/dfalib/fsck_journal.c
@@ -407,7 +407,11 @@ journal_open(int jfd,
uint32_t tempCksum; // Temporary checksum value
uint32_t jBlkSize = 0;
+#if LINUX
+ if (ioctl(jfd, BLKBSZGET, &jBlkSize) == -1) {
+#else
if (ioctl(jfd, DKIOCGETBLOCKSIZE, &jBlkSize) == -1) {
+#endif
jBlkSize = (uint32_t)min_fs_blksize;
} else {
if (jBlkSize < min_fs_blksize) {
diff --git a/fsck_hfs/fsck_hfs.c b/fsck_hfs/fsck_hfs.c
index 34b79de..2e00714 100644
--- a/fsck_hfs/fsck_hfs.c
+++ b/fsck_hfs/fsck_hfs.c
@@ -786,7 +786,11 @@ setup( char *dev, int *canWritePtr )
}
/* Get device block size to initialize cache */
+#if LINUX
+ if (ioctl(fsreadfd, BLKBSZGET, &devBlockSize) < 0) {
+#else
if (ioctl(fsreadfd, DKIOCGETBLOCKSIZE, &devBlockSize) < 0) {
+#endif
pfatal ("Can't get device block size\n");
return (0);
}
@@ -1019,14 +1023,25 @@ ScanDisk(int fd)
printStatus = 0; \
} while (0)
+#if LINUX
+ if (ioctl(fd, BLKBSZGET, &devBlockSize) == -1) {
+#else
if (ioctl(fd, DKIOCGETBLOCKSIZE, &devBlockSize) == -1) {
+#endif
devBlockSize = 512;
}
+#if LINUX
+ if (ioctl(fd, BLKGETSIZE64, &devBlockTotal) == -1) {
+ diskSize = 0;
+ } else
+ diskSize = devBlockTotal;
+#else
if (ioctl(fd, DKIOCGETBLOCKCOUNT, &devBlockTotal) == -1) {
diskSize = 0;
} else
diskSize = devBlockTotal * devBlockSize;
+#endif
while (buffer == NULL && bufSize >= devBlockSize) {
buffer = malloc(bufSize);
diff --git a/newfs_hfs/newfs_hfs.c b/newfs_hfs/newfs_hfs.c
index 7d7c3d6..fe42db0 100644
--- a/newfs_hfs/newfs_hfs.c
+++ b/newfs_hfs/newfs_hfs.c
@@ -914,6 +914,34 @@ hfs_newfs(char *device)
if (fstat( fso, &stbuf) < 0)
fatal("%s: %s", device, strerror(errno));
+#if LINUX
+ dip.sectorSize = 512;
+ dip.physSectorSize = 512;
+ dip.physSectorsPerIO = 1;
+#ifndef BLKGETSIZE
+#define BLKGETSIZE _IO(0x12,96)
+#endif
+#ifndef BLKGETSIZE64
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#endif
+
+ if (S_ISREG(stbuf.st_mode)) {
+ dip.totalSectors = stbuf.st_size / 512;
+ }
+ else if (S_ISBLK(stbuf.st_mode)) {
+ unsigned long size;
+ u_int64_t size64;
+ if (!ioctl(fso, BLKGETSIZE64, &size64))
+ dip.totalSectors = size64 / 512;
+ else if (!ioctl(fso, BLKGETSIZE, &size))
+ dip.totalSectors = size;
+ else
+ fatal("%s: %s", device, strerror(errno));
+ }
+ else
+ fatal("%s: is not a block device", device);
+ }
+#else
if (ioctl(fso, DKIOCGETBLOCKSIZE, &dip.physSectorSize) < 0)
fatal("%s: %s", device, strerror(errno));
@@ -953,6 +981,7 @@ hfs_newfs(char *device)
dip.sectorSize = kBytesPerSector;
dip.totalSectors = dip.physTotalSectors * dip.physSectorSize / dip.sectorSize;
+#endif
dip.sectorOffset = 0;
time(&createtime);
--
2.41.0