From 96efb782cadd7c78d702017f0009d28f41a33d8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli@nabijaczleweli.xyz>
Date: Sat, 9 Nov 2024 01:17:41 +0100
Subject: [PATCH] Allow building with fuse3 in addition to the current fuse2

fuse3 is preferred of course
---
 CMakeLists.txt | 28 ++++++++--------------------
 fusefatfs.c    | 28 ++++++++++++++++++++--------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 31a34c3..5e7d70e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,33 +9,22 @@ include(GNUInstallDirs)
 include(CheckIncludeFile)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
 
-# check availability of headers and libs
-set(HEADERS_REQUIRED fuse.h)
-set(LIBS_REQUIRED fuse)
+find_package(PkgConfig)
+pkg_check_modules(FUSE fuse3)
+if(NOT FUSE_FOUND)
+	pkg_check_modules(FUSE REQUIRED fuse)
+endif()
+string(REGEX REPLACE "\\..*" "" FUSE_VERSION ${FUSE_VERSION})
 
 set(CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
 
-foreach(HEADER IN LISTS HEADERS_REQUIRED)
-  check_include_file(${HEADER} ${HEADER}_OK)
-  if(NOT ${HEADER}_OK)
-    message(FATAL_ERROR "header file ${HEADER} not found")
-  endif()
-endforeach(HEADER)
-
-foreach(THISLIB IN LISTS LIBS_REQUIRED)
-  find_library(LIB${THISLIB}_OK ${THISLIB})
-  if(NOT LIB${THISLIB}_OK)
-    message(FATAL_ERROR "library lib${THISLIB} not found")
-  endif()
-endforeach(THISLIB)
-
 configure_file(config.h.in config.h @ONLY)
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2 -O2 -pedantic -Wall -Wextra")
 
-add_definitions(-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64)
+add_definitions(-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 ${FUSE_CFLAGS} -DFUSE=${FUSE_VERSION})
 
 add_executable(fusefatfs fusefatfs.c fftable.c diskio.c ff.c ffunicode.c)
-target_link_libraries(fusefatfs fuse)
+target_link_libraries(fusefatfs ${FUSE_LIBRARIES})
 install(TARGETS fusefatfs
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 
@@ -49,4 +38,3 @@ add_subdirectory(man)
 add_custom_target(uninstall
   "${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/Uninstall.cmake"
   )
-
diff --git a/fusefatfs.c b/fusefatfs.c
index cebd996..c2aa7e4 100644
--- a/fusefatfs.c
+++ b/fusefatfs.c
@@ -16,7 +16,13 @@
  *
  */
 
+#if FUSE == 2
 #define FUSE_USE_VERSION 29
+#define FUSE3_ONLY(...)
+#else
+#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 14)
+#define FUSE3_ONLY(...) __VA_ARGS__
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -113,8 +119,9 @@ static time_t fftime2time(WORD fdate, WORD ftime) {
 	}
 }
 
-static int fff_getattr(const char *path, struct stat *stbuf)
+static int fff_getattr(const char *path, struct stat *stbuf FUSE3_ONLY(, struct fuse_file_info *fi))
 {
+	FUSE3_ONLY((void) fi);
 	mutex_in();
 	struct fuse_context *cntx=fuse_get_context();
 	struct fftab *ffentry = cntx->private_data;
@@ -253,9 +260,10 @@ static int fff_releasedir(const char *path, struct fuse_file_info *fi){
 }
 
 static int fff_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-		off_t offset, struct fuse_file_info *fi){
+		off_t offset, struct fuse_file_info *fi FUSE3_ONLY(, enum fuse_readdir_flags fl)){
 	(void) offset;
 	(void) fi;
+	FUSE3_ONLY((void) fl);
 	mutex_in();
 	struct fuse_context *cntx=fuse_get_context();
 	struct fftab *ffentry = cntx->private_data;
@@ -264,14 +272,14 @@ static int fff_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
 	FRESULT fres = f_opendir(&dp, fffpath);
 	if (fres != FR_OK)
 		goto mutexout_leave;
-	filler(buf, ".", NULL, 0);
-	filler(buf, "..", NULL, 0);
+	filler(buf, ".", NULL, 0 FUSE3_ONLY(, 0));
+	filler(buf, "..", NULL, 0 FUSE3_ONLY(, 0));
 	while(1) {
 		FILINFO fileinfo;
 		fres = f_readdir(&dp, &fileinfo);
 		if (fres != FR_OK) break;
 		if (fileinfo.fname[0] == 0) break;
-		filler(buf, fileinfo.fname, NULL, 0);
+		filler(buf, fileinfo.fname, NULL, 0 FUSE3_ONLY(, 0));
 	}
 	f_closedir(&dp);
 mutexout_leave:
@@ -316,7 +324,9 @@ static int fff_rmdir(const char *path) {
 	mutex_out_return(fr2errno(fres));
 }
 
-static int fff_rename(const char *path, const char *newpath) {
+static int fff_rename(const char *path, const char *newpath FUSE3_ONLY(, unsigned int flags)) {
+	FUSE3_ONLY(if(flags) return -ENOSYS;)
+
 	mutex_in();
 	struct fuse_context *cntx=fuse_get_context();
 	struct fftab *ffentry = cntx->private_data;
@@ -327,7 +337,8 @@ static int fff_rename(const char *path, const char *newpath) {
 	mutex_out_return(fr2errno(fres));
 }
 
-static int fff_truncate(const char *path, off_t size) {
+static int fff_truncate(const char *path, off_t size FUSE3_ONLY(, struct fuse_file_info *fi)) {
+	FUSE3_ONLY((void) fi);
 	mutex_in();
 	struct fuse_context *cntx=fuse_get_context();
 	struct fftab *ffentry = cntx->private_data;
@@ -350,7 +361,8 @@ static int fff_truncate(const char *path, off_t size) {
 	mutex_out_return(fr2errno(fres));
 }
 
-static int fff_utimens(const char *path, const struct timespec tv[2]) {
+static int fff_utimens(const char *path, const struct timespec tv[2] FUSE3_ONLY(, struct fuse_file_info *fi)) {
+	FUSE3_ONLY((void) fi);
 	mutex_in();
 	struct fuse_context *cntx=fuse_get_context();
   struct fftab *ffentry = cntx->private_data;
