pax_global_header00006660000000000000000000000064136533453560014527gustar00rootroot0000000000000052 comment=27d5749e7c9989691905df0b54583df42be30146 tmfs-r7/000077500000000000000000000000001365334535600123725ustar00rootroot00000000000000tmfs-r7/AUTHORS000066400000000000000000000001211365334535600134340ustar00rootroot00000000000000Alexandre Bique Tor Arne Vestbø tmfs-r7/CMakeLists.txt000066400000000000000000000011501365334535600151270ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.16) project(TMFS CXX) set(CMAKE_CXX_STANDARD 17) find_package(PkgConfig) pkg_check_modules(FUSE REQUIRED fuse) add_definitions(${FUSE_CFLAGS} -Wall) include_directories(${Boost_INCLUDE_DIRS}) add_executable(tmfs src/main.cc src/readdir.cc src/read.cc src/readlink.cc src/getattr.cc src/get_real_path.cc ) link_directories(${FUSE_LIBRARY_DIRS}) target_link_libraries(tmfs ${FUSE_LIBRARIES}) install(TARGETS tmfs RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) tmfs-r7/ChangeLog000066400000000000000000000007671365334535600141560ustar00rootroot000000000000002013-03-12 Alexandre Bique * release: 4 * dependancies: need boost >= 1.42 * improves readme and help message * handle hard-links inside of .HFS+ Private Directory Data 2012-07-23 Alexandre Bique * release: 3 2012-03-21 Alexandre Bique * license: change to MIT 2011-07-08 Alexandre Bique * release: 2 * dependancies: switched from C++0x to standard C++ * release: 1 tmfs-r7/LICENSE000066400000000000000000000020501365334535600133740ustar00rootroot00000000000000Copyright (C) 2011-2012 Alexandre Bique Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tmfs-r7/README.markdown000066400000000000000000000045111365334535600150740ustar00rootroot00000000000000TMFS ==== ``` __/\\\\\\\\\\\\\\\___/\\\\____________/\\\\___/\\\\\\\\\\\\\\\______/\\\\\\\\\\\___ _\///////\\\/////___\/\\\\\\________/\\\\\\__\/\\\///////////_____/\\\/////////\\\_ _______\/\\\________\/\\\//\\\____/\\\//\\\__\/\\\_______________\//\\\______\///__ _______\/\\\________\/\\\\///\\\/\\\/_\/\\\__\/\\\\\\\\\\\________\////\\\_________ _______\/\\\________\/\\\__\///\\\/___\/\\\__\/\\\///////____________\////\\\______ _______\/\\\________\/\\\____\///_____\/\\\__\/\\\______________________\////\\\___ _______\/\\\________\/\\\_____________\/\\\__\/\\\_______________/\\\______\//\\\__ _______\/\\\________\/\\\_____________\/\\\__\/\\\______________\///\\\\\\\\\\\/___ _______\///_________\///______________\///___\///_________________\///////////_____ ``` Time Machine File System is a read-only virtual filesystem which helps you to read your Apple's time machine backup. This filesystem does not targets performances, it has been written for a friend who has lost his macbook and wants to recover its data on Linux. It's actually not perfect, feel free to report bugs or suggestions at [https://github.com/abique/tmfs/issues][https://github.com/abique/tmfs/issues]. Enjoy! How to use it? -------------- First you have to mount your HFS partition, by doing something like: `mount /dev/sdXX /mnt/hfs-root` Then as root run: `tmfs /mnt/hfs-root /mnt/tm-root -ouid=$(id -u),gid=$(id -g),allow_other` Then as a normal user, go to the directory /mnt/tm-root/ and enjoy your data! :-) Dependancies ------------ - c++ - cmake >= 2.8 - boost >= 1.42.0 (earlier versions may also work, but are untested) - fuse How to build and install it? ---------------------------- Manually, run these commands: ``` mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. make DESTDIR=install-test make install ``` Then if the installation looks ok to you in install-test/ do make install as root with `sudo make install`. Internals --------- Time Machine structure: Snapshot root: `${hfs_root}/Backups.backupdb/${comp_name}/${date}/${disk_name}/` Hardlink count equals to dir_id: `${hfs_root}/Backups.backupdb/${comp_name}/${date}/${disk_name}/.../Folder` Real folder with data: `${hfs_root}/.HFS+ Private Directory Data/dir_${dir_id}/` Our representation: `/${comp_name}/${date}/${disk_name}/${Real root}` tmfs-r7/src/000077500000000000000000000000001365334535600131615ustar00rootroot00000000000000tmfs-r7/src/get_real_path.cc000066400000000000000000000026701365334535600162730ustar00rootroot00000000000000#include "tmfs.hh" static std::string _get_real_path(const std::string & str) { // use the relative path so that the real_path doesn't get replaced const auto clean_path = fs::path(str).relative_path(); fs::path real_path(tmfs::instance().hfs_root()); real_path /= "Backups.backupdb"; // ${hfs_root}/Backups.backupdb/ // ok let's copy the 3 first part of the virtual path // (${comp_name}, ${date}, ${disk_name}) auto it = clean_path.begin(); for (int i = 0; i < 3 && it != clean_path.end(); ++i, ++it) real_path /= *it; // let's resolv all the parts of the path struct stat stbuf; for (; it != clean_path.end(); ++it) { real_path /= *it; // Does the file exists ? if (stat(real_path.string().c_str(), &stbuf)) return real_path.string(); // Is the file a dir_id ? if (S_ISREG(stbuf.st_mode) && stbuf.st_size == 0 && stbuf.st_nlink > 0) { // build the real path std::ostringstream os; os << tmfs::instance().hfs_root() << "/.HFS+ Private Directory Data\r/dir_" << stbuf.st_nlink; // check if it's really a ${dir_id} if (stat(os.str().c_str(), &stbuf)) continue; // it's not real_path = os.str(); // it is } } return real_path.string(); } std::string get_real_path(const std::string & str) { auto result = _get_real_path(str); #ifndef NDEBUG std::cout << "get_real_path(\"" << str << "\") -> " << result << std::endl; #endif return result; } tmfs-r7/src/getattr.cc000066400000000000000000000004521365334535600151430ustar00rootroot00000000000000#include "tmfs.hh" int tmfs_getattr(const char *path, struct stat *stbuf) { // get the real path std::string real_path = get_real_path(path); // and now just stat the real path memset(stbuf, 0, sizeof(struct stat)); if (lstat(real_path.c_str(), stbuf)) return -errno; return 0; } tmfs-r7/src/main.cc000066400000000000000000000017101365334535600144130ustar00rootroot00000000000000#include "tmfs.hh" int main(int argc, char ** argv) { if (argc < 3) { fprintf(stderr, "Usage: %s: