Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FreeBSD support #139

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ApfsLib/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "DeviceWinPhys.h"
#include "DeviceLinux.h"
#include "DeviceMac.h"
#include "DeviceBSD.h"
#include "DeviceDMG.h"
#include "DeviceSparseImage.h"
#include "DeviceVDI.h"
Expand Down Expand Up @@ -97,6 +98,10 @@ Device * Device::OpenDevice(const char * name)
#ifdef __APPLE__
dev = new DeviceMac();
#endif
#if defined (__FreeBSD__)
dev = new DeviceBSD();
#endif

rc = dev->Open(name);

if (!rc)
Expand Down
125 changes: 125 additions & 0 deletions ApfsLib/DeviceBSD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
This file is part of apfs-fuse, a read-only implementation of APFS
(Apple File System) for FUSE.
Copyright (C) 2017 Simon Gander
Copyright (C) 2021 John Othwolo

Apfs-fuse 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.

Apfs-fuse 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 apfs-fuse. If not, see <http://www.gnu.org/licenses/>.
*/

#if defined (__FreeBSD__) // check other BSDs

#include <unistd.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <iostream>

#include "DeviceBSD.h"
#include "Global.h"

DeviceBSD::DeviceBSD()
{
m_device = -1;
m_size = 0;
}

DeviceBSD::~DeviceBSD()
{
Close();
}

bool DeviceBSD::Open(const char* name)
{
m_device = open(name, O_RDONLY);

if (m_device == -1)
{
std::cout << "Opening device " << name << " failed with error " << strerror(errno) << std::endl;
return false;
}

struct stat st;

fstat(m_device, &st);

std::cout << "st_mode = " << st.st_mode << std::endl;

if (S_ISREG(st.st_mode))
{
m_size = st.st_size;
}
else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))
{
// uint64_t sector_count = 0;
uint32_t sector_size = 0;
uint32_t media_size = 0;

ioctl(m_device, DIOCGMEDIASIZE, &media_size);
// ioctl(m_device, DKIOCGETBLOCKCOUNT, &sector_count);
ioctl(m_device, DIOCGSECTORSIZE, &sector_size);

// m_size = sector_size * sector_count;
m_size = media_size;

if ((media_size%sector_size) != 0)
{
std::cerr << "Something is really wrong!!";
}
// std::cout << "Sector count = " << sector_count << std::endl;
std::cout << "Sector size = " << sector_size << std::endl;
std::cout << "Media size = " << media_size << std::endl;
}
else
{
std::cout << "File mode unknown!" << std::endl;
}

if (g_debug & Dbg_Info)
std::cout << "Device " << name << " opened. Size is " << m_size << std::endl;

return m_device != -1;
}

void DeviceBSD::Close()
{
if (m_device != -1)
close(m_device);
m_device = -1;
m_size = 0;
}

bool DeviceBSD::Read(void* data, uint64_t offs, uint64_t len)
{
size_t nread;

nread = pread(m_device, data, len, offs);

// TODO: Better error handling ...
return nread == len;
}

bool DeviceBSD::Write(void* data, uint64_t offs, uint64_t len)
{
// TODO: Better error handling ...
return len == static_cast<uint64_t >(pwrite(m_device, data, len, offs));
}

#endif

46 changes: 46 additions & 0 deletions ApfsLib/DeviceBSD.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
This file is part of apfs-fuse, a read-only implementation of APFS
(Apple File System) for FUSE.
Copyright (C) 2017 Simon Gander
Copyright (C) 2021 John Othwolo

Apfs-fuse 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.

Apfs-fuse 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 apfs-fuse. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#if defined (__FreeBSD__)

#include "Device.h"

class DeviceBSD : public Device
{
public:
DeviceBSD();
~DeviceBSD();

bool Open(const char *name) override;
void Close() override;

bool Read(void *data, uint64_t offs, uint64_t len) override;
bool Write(void *data, uint64_t offs, uint64_t len);

uint64_t GetSize() const override { return m_size; }

private:
int m_device;
uint64_t m_size;
};

#endif
8 changes: 8 additions & 0 deletions ApfsLib/Endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ Also helps making the driver run on big-endian architectures.
// Definitions for Linux
#include <byteswap.h>
#include <endian.h>
#endif
#ifdef __FreeBSD__
#include <sys/endian.h>

#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64

#endif
#ifdef __APPLE__
// Definitions for macOS
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ add_library(apfs
ApfsLib/DeviceLinux.h
ApfsLib/DeviceMac.cpp
ApfsLib/DeviceMac.h
ApfsLib/DeviceBSD.h
ApfsLib/DeviceBSD.cpp
ApfsLib/DeviceSparseImage.cpp
ApfsLib/DeviceSparseImage.h
ApfsLib/DeviceWinFile.cpp
Expand Down Expand Up @@ -121,6 +123,10 @@ target_include_directories(apfs-fuse PRIVATE /usr/local/include/osxfuse/)
# link_directories(/usr/local/lib/)
target_link_libraries(apfs-fuse apfs /usr/local/lib/libosxfuse.dylib)
else()
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
target_include_directories(apfs-fuse PRIVATE /usr/local/include/)
link_directories(/usr/local/lib/)
endif()
if (USE_FUSE3)
target_link_libraries(apfs-fuse apfs fuse3)
else()
Expand Down
9 changes: 7 additions & 2 deletions apfsfuse/ApfsFuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define FUSE_USE_VERSION 30
#endif

#ifdef __linux__
#if defined (__linux__)
#ifdef USE_FUSE2
#include <fuse/fuse.h>
#include <fuse/fuse_lowlevel.h>
Expand All @@ -33,7 +33,7 @@
#endif
#include <unistd.h>
#endif
#ifdef __APPLE__
#if defined (__APPLE__) || defined (__FreeBSD__)
#include <fuse/fuse.h>
#include <fuse/fuse_lowlevel.h>
#endif
Expand All @@ -49,6 +49,7 @@
#include <ApfsLib/Decmpfs.h>
#include <ApfsLib/DeviceLinux.h>
#include <ApfsLib/DeviceMac.h>
#include <ApfsLib/DeviceBSD.h>
#include <ApfsLib/GptPartitionMap.h>

#include <cassert>
Expand All @@ -57,6 +58,10 @@

#include <iostream>

#ifdef __FreeBSD__
#include <unistd.h>
#endif

static_assert(sizeof(fuse_ino_t) == 8, "Sorry, on 32-bit systems, you need to use FUSE-3.");

constexpr double FUSE_TIMEOUT = 86400.0;
Expand Down