diff --git a/Makefile.am b/Makefile.am index ad5966e..2c3841f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,6 @@ -SUBDIRS = libudffs mkudffs cdrwtool pktsetup udffsck udfinfo udflabel wrudf doc +SUBDIRS = libudffs mkudffs udffsck udfinfo udflabel doc +if LINUX_TOOLS +SUBDIRS += cdrwtool pktsetup wrudf +endif dist_doc_DATA = AUTHORS COPYING NEWS README EXTRA_DIST = autogen.sh Doxyfile diff --git a/configure.ac b/configure.ac index 30aa656..328eb09 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,12 @@ AC_SUBST(LTLIBOBJS) AM_CONDITIONAL(USE_READLINE, test "$readline_found" = "yes") -AC_CONFIG_FILES(Makefile libudffs/Makefile mkudffs/Makefile cdrwtool/Makefile pktsetup/Makefile udffsck/Makefile udfinfo/Makefile udflabel/Makefile wrudf/Makefile doc/Makefile) +dnl Check for Linux-only tools (cdrwtool, pktsetup, wrudf depend on linux/cdrom.h) +AC_CHECK_HEADER([linux/cdrom.h], [have_linux_cdrom=yes], [have_linux_cdrom=no]) +AM_CONDITIONAL(LINUX_TOOLS, [test "$have_linux_cdrom" = "yes"]) + +AC_CONFIG_FILES(Makefile libudffs/Makefile mkudffs/Makefile udffsck/Makefile udfinfo/Makefile udflabel/Makefile doc/Makefile) +AS_IF([test "$have_linux_cdrom" = "yes"], + [AC_CONFIG_FILES(cdrwtool/Makefile pktsetup/Makefile wrudf/Makefile)]) AC_OUTPUT diff --git a/mkudffs/main.c b/mkudffs/main.c index 92919d4..9a4fdf1 100644 --- a/mkudffs/main.c +++ b/mkudffs/main.c @@ -41,9 +41,13 @@ #include #include #include +#ifdef __linux__ #include #include #include +#elif defined(__APPLE__) +#include +#endif #include "mkudffs.h" #include "defaults.h" @@ -71,6 +75,10 @@ static uint32_t get_blocks(int fd, int blocksize, uint32_t opt_blocks) #endif #ifdef FDGETPRM struct floppy_struct this_floppy; +#endif +#ifdef __APPLE__ + uint32_t dk_block_size; + uint64_t dk_block_count; #endif struct stat buf; @@ -80,6 +88,12 @@ static uint32_t get_blocks(int fd, int blocksize, uint32_t opt_blocks) if (fd <= 0) return 0; +#ifdef __APPLE__ + if (ioctl(fd, DKIOCGETBLOCKSIZE, &dk_block_size) >= 0 && + ioctl(fd, DKIOCGETBLOCKCOUNT, &dk_block_count) >= 0) + blocks = (uint64_t)dk_block_size * dk_block_count / blocksize; + else +#endif #ifdef BLKGETSIZE64 if (ioctl(fd, BLKGETSIZE64, &size64) >= 0) blocks = size64 / blocksize; @@ -128,11 +142,20 @@ static uint32_t get_blocks(int fd, int blocksize, uint32_t opt_blocks) static void detect_blocksize(int fd, struct udf_disc *disc, int *blocksize) { -#ifdef BLKSSZGET +#if defined(BLKSSZGET) || defined(__APPLE__) int size; +#ifdef __APPLE__ + { + uint32_t dk_size; + if (ioctl(fd, DKIOCGETBLOCKSIZE, &dk_size) != 0 || dk_size <= 0) + return; + size = dk_size; + } +#else if (ioctl(fd, BLKSSZGET, &size) != 0 || size <= 0) return; +#endif if (!disc->blkssz) disc->blkssz = size; diff --git a/mkudffs/mkudffs.c b/mkudffs/mkudffs.c index e704e94..aee69f6 100644 --- a/mkudffs/mkudffs.c +++ b/mkudffs/mkudffs.c @@ -40,7 +40,9 @@ #include #include #include +#ifdef __linux__ #include +#endif #include "mkudffs.h" #include "file.h" @@ -614,7 +616,9 @@ static void fill_mbr(struct udf_disc *disc, struct mbr *mbr, uint32_t start) struct mbr old_mbr; uint64_t lba_blocks; struct stat st; +#ifdef __linux__ struct hd_geometry geometry; +#endif unsigned int heads, sectors; struct mbr_partition *mbr_partition; unsigned int blkssz = disc->blkssz ? disc->blkssz : 512; @@ -643,12 +647,14 @@ static void fill_mbr(struct udf_disc *disc, struct mbr *mbr, uint32_t start) lba_blocks = ((uint64_t)disc->blocks * disc->blocksize + blkssz - 1) / blkssz; +#ifdef __linux__ if (fd >= 0 && fstat(fd, &st) == 0 && S_ISBLK(st.st_mode) && ioctl(fd, HDIO_GETGEO, &geometry) == 0) { heads = geometry.heads; sectors = geometry.sectors; } else +#endif { /* Use LBA-Assist Translation for calculating CHS when disk geometry is not available */ sectors = 63; diff --git a/mkudffs/options.c b/mkudffs/options.c index e2acd11..1c7a588 100644 --- a/mkudffs/options.c +++ b/mkudffs/options.c @@ -40,7 +40,9 @@ #include #include #include +#ifdef __linux__ #include +#endif #include "mkudffs.h" #include "defaults.h" @@ -741,6 +743,7 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in * pktcdvd.ko accepts only these ioctls: * CDROMEJECT CDROMMULTISESSION CDROMREADTOCENTRY * CDROM_LAST_WRITTEN CDROM_SEND_PACKET SCSI_IOCTL_SEND_COMMAND */ +#ifdef __linux__ if (fd >= 0 && fstat(fd, &st) == 0 && S_ISBLK(st.st_mode) && ioctl(fd, CDROM_LAST_WRITTEN, &last) == 0) { struct cdrom_generic_command cgc; @@ -808,6 +811,7 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in } } } +#endif if (fd >= 0) close(fd); diff --git a/udfinfo/main.c b/udfinfo/main.c index 03a7041..49fb86b 100644 --- a/udfinfo/main.c +++ b/udfinfo/main.c @@ -31,8 +31,12 @@ #include #include -#include #include +#ifdef __linux__ +#include +#elif defined(__APPLE__) +#include +#endif #include "libudffs.h" #include "options.h" @@ -46,9 +50,20 @@ static uint64_t get_size(int fd) if (fstat(fd, &st) == 0) { +#ifdef __linux__ if (S_ISBLK(st.st_mode) && ioctl(fd, BLKGETSIZE64, &size) == 0) return size; - else if (S_ISREG(st.st_mode)) +#elif defined(__APPLE__) + if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) + { + uint32_t block_size; + uint64_t block_count; + if (ioctl(fd, DKIOCGETBLOCKSIZE, &block_size) == 0 && + ioctl(fd, DKIOCGETBLOCKCOUNT, &block_count) == 0) + return (uint64_t)block_size * block_count; + } +#endif + if (S_ISREG(st.st_mode)) return st.st_size; } @@ -72,8 +87,15 @@ static int get_sector_size(int fd) { int size; +#ifdef __linux__ if (ioctl(fd, BLKSSZGET, &size) != 0) return 0; +#elif defined(__APPLE__) + if (ioctl(fd, DKIOCGETBLOCKSIZE, &size) != 0) + return 0; +#else + return 0; +#endif if (size < 512 || size > 32768 || (size & (size - 1))) { diff --git a/udfinfo/readdisc.c b/udfinfo/readdisc.c index 7b4e2f5..4248e78 100644 --- a/udfinfo/readdisc.c +++ b/udfinfo/readdisc.c @@ -29,8 +29,10 @@ #include #include -#include #include +#ifdef __linux__ +#include +#endif #include "libudffs.h" #include "readdisc.h" @@ -349,16 +351,20 @@ static int detect_udf(int fd, struct udf_disc *disc) int found_vrs = 0; uint64_t start = 0; uint64_t last = 0; +#ifdef __linux__ long last_written; - struct stat st; struct cdrom_multisession multisession; +#endif + struct stat st; if (disc->start_block == (uint32_t)-1) { +#ifdef __linux__ memset(&multisession, 0, sizeof(multisession)); multisession.addr_format = CDROM_LBA; if (fstat(fd, &st) == 0 && S_ISBLK(st.st_mode) && ioctl(fd, CDROMMULTISESSION, &multisession) == 0 && multisession.xa_flag) start = (uint64_t)multisession.addr.lba * (disc->blkssz ? disc->blkssz : 2048); +#endif if (!start) disc->start_block = 0; } @@ -367,8 +373,10 @@ static int detect_udf(int fd, struct udf_disc *disc) { if (disc->vat_block) disc->last_block = disc->vat_block; +#ifdef __linux__ else if (fstat(fd, &st) == 0 && S_ISBLK(st.st_mode) && ioctl(fd, CDROM_LAST_WRITTEN, &last_written) == 0) last = (uint64_t)last_written * (disc->blkssz ? disc->blkssz : 2048); +#endif else last = (uint64_t)-1; } diff --git a/udflabel/main.c b/udflabel/main.c index d2c9af4..ac89b81 100644 --- a/udflabel/main.c +++ b/udflabel/main.c @@ -31,8 +31,12 @@ #include #include -#include #include +#ifdef __linux__ +#include +#elif defined(__APPLE__) +#include +#endif #include "libudffs.h" #include "options.h" @@ -46,9 +50,20 @@ static uint64_t get_size(int fd) if (fstat(fd, &st) == 0) { +#ifdef __linux__ if (S_ISBLK(st.st_mode) && ioctl(fd, BLKGETSIZE64, &size) == 0) return size; - else if (S_ISREG(st.st_mode)) +#elif defined(__APPLE__) + if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) + { + uint32_t block_size; + uint64_t block_count; + if (ioctl(fd, DKIOCGETBLOCKSIZE, &block_size) == 0 && + ioctl(fd, DKIOCGETBLOCKCOUNT, &block_count) == 0) + return (uint64_t)block_size * block_count; + } +#endif + if (S_ISREG(st.st_mode)) return st.st_size; } @@ -72,8 +87,15 @@ static int get_sector_size(int fd) { int size; +#ifdef __linux__ if (ioctl(fd, BLKSSZGET, &size) != 0) return 0; +#elif defined(__APPLE__) + if (ioctl(fd, DKIOCGETBLOCKSIZE, &size) != 0) + return 0; +#else + return 0; +#endif if (size < 512 || size > 32768 || (size & (size - 1))) { @@ -779,7 +801,11 @@ int main(int argc, char *argv[]) printf("Synchronizing...\n"); if (!(disc.flags & FLAG_NO_WRITE)) { +#ifdef __APPLE__ + if (fcntl(fd, F_FULLFSYNC) != 0) +#else if (fdatasync(fd) != 0) +#endif { fprintf(stderr, "%s: Error: Synchronization to device '%s' failed: %s\n", appname, filename, strerror(errno)); exit(1);