diff --git a/setter/src/darwin/darwin.h b/setter/src/darwin/darwin.h index 36009a1..e6bd131 100644 --- a/setter/src/darwin/darwin.h +++ b/setter/src/darwin/darwin.h @@ -12,5 +12,6 @@ void DarwinPrintStatfsFlags(uint32_t flags); void DarwinResourceFork(const char* path); void DarwinFileAttributes(const char* path); void DarwinExtendedAttributes(const char* path); +void DarwinVolumeAttributes(const char* path); #endif // SETTER_SRC_DARWIN_DARWIN_H_ diff --git a/setter/src/darwin/volume.c b/setter/src/darwin/volume.c index 0345733..041918f 100644 --- a/setter/src/darwin/volume.c +++ b/setter/src/darwin/volume.c @@ -22,6 +22,10 @@ Aaru Data Preservation Suite Copyright (C) 2011-2021 Natalia Portillo *****************************************************************************/ +#include +#include +#include + #include "volume.h" #include "../log.h" @@ -179,4 +183,187 @@ void DarwinPrintStatfsFlags(uint32_t flags) } if(flags) { log_write("\t\tRemaining flags: 0x%08lX\n", flags); } +} + +typedef struct attrlist attrlist_t; + +void DarwinVolumeAttributes(const char* path) +{ + int ret; + attrlist_t attrList; + vol_capabilities_attr_t attrBuf; + u_int32_t capabilities_valid; + + memset(&attrList, 0, sizeof(attrList)); + memset(&attrBuf, 0, sizeof(vol_capabilities_attr_t)); + + attrList.bitmapcount = ATTR_BIT_MAP_COUNT; + attrList.volattr = ATTR_VOL_CAPABILITIES; + + ret = getattrlist(path, &attrList, &attrBuf, sizeof(attrBuf), 0); + if(ret) + { + log_write("Error %d retrieving volume capabilities.\n", errno); + return; + } + + log_write("Darwin volume capabilities:\n"); + + capabilities_valid = attrBuf.valid[VOL_CAPABILITIES_FORMAT]; + + if(capabilities_valid & VOL_CAP_FMT_PERSISTENTOBJECTIDS) + { + log_write("\tVolume has persistent object IDs.\n"); + capabilities_valid -= VOL_CAP_FMT_PERSISTENTOBJECTIDS; + } + + if(capabilities_valid & VOL_CAP_FMT_SYMBOLICLINKS) + { + log_write("\tVolume supports symbolic links.\n"); + capabilities_valid -= VOL_CAP_FMT_SYMBOLICLINKS; + } + + if(capabilities_valid & VOL_CAP_FMT_HARDLINKS) + { + log_write("\tVolume supports hard links\n"); + capabilities_valid -= VOL_CAP_FMT_HARDLINKS; + } + + if(capabilities_valid & VOL_CAP_FMT_JOURNAL) + { + log_write("\tVolume support recovery journal\n"); + capabilities_valid -= VOL_CAP_FMT_JOURNAL; + } + + if(capabilities_valid & VOL_CAP_FMT_JOURNAL_ACTIVE) + { + log_write("\tVolume is using a recovery journal\n"); + capabilities_valid -= VOL_CAP_FMT_JOURNAL_ACTIVE; + } + + if(capabilities_valid & VOL_CAP_FMT_NO_ROOT_TIMES) + { + log_write("\tVolume does not store reliable times for the root directory\n"); + capabilities_valid -= VOL_CAP_FMT_NO_ROOT_TIMES; + } + + if(capabilities_valid & VOL_CAP_FMT_SPARSE_FILES) + { + log_write("\tVolume supports sparse files\n"); + capabilities_valid -= VOL_CAP_FMT_SPARSE_FILES; + } + + if(capabilities_valid & VOL_CAP_FMT_ZERO_RUNS) + { + log_write("\tVolume returns zeros for parts of a file that have never been written\n"); + capabilities_valid -= VOL_CAP_FMT_ZERO_RUNS; + } + + if(capabilities_valid & VOL_CAP_FMT_CASE_SENSITIVE) + { + log_write("\tVolume uses case sensitive name comparison\n"); + capabilities_valid -= VOL_CAP_FMT_CASE_SENSITIVE; + } + + if(capabilities_valid & VOL_CAP_FMT_CASE_PRESERVING) + { + log_write("\tVolume uses case insensitive name comparison but stores names with cases\n"); + capabilities_valid -= VOL_CAP_FMT_CASE_PRESERVING; + } + + if(capabilities_valid & VOL_CAP_FMT_FAST_STATFS) + { + log_write("\tVolume returns from statfs(2) fast enough to not need to cache it\n"); + capabilities_valid -= VOL_CAP_FMT_FAST_STATFS; + } + + if(capabilities_valid & VOL_CAP_FMT_2TB_FILESIZE) + { + log_write("\tVolume supports file sizes larger than 4Gb, up to AT LEAST 2Tb (or higher)\n"); + capabilities_valid -= VOL_CAP_FMT_2TB_FILESIZE; + } + + if(capabilities_valid & VOL_CAP_FMT_OPENDENYMODES) + { + log_write("\tVolume support deny modes when opening files\n"); + capabilities_valid -= VOL_CAP_FMT_OPENDENYMODES; + } + + if(capabilities_valid & VOL_CAP_FMT_HIDDEN_FILES) + { + log_write("\tVolume supports the hidden/invisible flag\n"); + capabilities_valid -= VOL_CAP_FMT_HIDDEN_FILES; + } + + if(capabilities_valid & VOL_CAP_FMT_PATH_FROM_ID) + { + log_write("\tVolume can derive a path from an object ID\n"); + capabilities_valid -= VOL_CAP_FMT_PATH_FROM_ID; + } + + if(capabilities_valid & VOL_CAP_FMT_NO_VOLUME_SIZES) + { + log_write("\tVolume sizes in blocks returned in statfs(2) are not valid\n"); + capabilities_valid -= VOL_CAP_FMT_NO_VOLUME_SIZES; + } + + if(capabilities_valid & VOL_CAP_FMT_DECMPFS_COMPRESSION) + { + log_write("\tVolume transparently decompresses files\n"); + capabilities_valid -= VOL_CAP_FMT_DECMPFS_COMPRESSION; + } + + if(capabilities_valid & VOL_CAP_FMT_64BIT_OBJECT_IDS) + { + log_write("\tVolume object IDs are 64-bit long\n"); + capabilities_valid -= VOL_CAP_FMT_64BIT_OBJECT_IDS; + } + + if(capabilities_valid & VOL_CAP_FMT_DIR_HARDLINKS) + { + log_write("\tVolume supports directory hard links\n"); + capabilities_valid -= VOL_CAP_FMT_DIR_HARDLINKS; + } + + if(capabilities_valid & VOL_CAP_FMT_DOCUMENT_ID) + { + log_write("\tVolume supports document IDs with revisions\n"); + capabilities_valid -= VOL_CAP_FMT_DOCUMENT_ID; + } + + if(capabilities_valid & VOL_CAP_FMT_WRITE_GENERATION_COUNT) + { + log_write("\tVolume supports write generation count\n"); + capabilities_valid -= VOL_CAP_FMT_WRITE_GENERATION_COUNT; + } + + if(capabilities_valid & VOL_CAP_FMT_NO_IMMUTABLE_FILES) + { + log_write("\tVolume does not support the immutable flag\n"); + capabilities_valid -= VOL_CAP_FMT_NO_IMMUTABLE_FILES; + } + + if(capabilities_valid & VOL_CAP_FMT_NO_PERMISSIONS) + { + log_write("\tVolume does not support setting file permissions\n"); + capabilities_valid -= VOL_CAP_FMT_NO_PERMISSIONS; + } + + if(capabilities_valid & VOL_CAP_FMT_SHARED_SPACE) + { + log_write("\tVolume support sharing space with multiple volumes\n"); + capabilities_valid -= VOL_CAP_FMT_SHARED_SPACE; + } + + if(capabilities_valid & VOL_CAP_FMT_VOL_GROUPS) + { + log_write("\tVolume supports mounting several volumes at once\n"); + capabilities_valid -= VOL_CAP_FMT_VOL_GROUPS; + } + + if(capabilities_valid & VOL_CAP_FMT_SEALED) + { + log_write("\tVolume is cryptographically sealed\n"); + capabilities_valid -= VOL_CAP_FMT_SEALED; + } } \ No newline at end of file diff --git a/setter/src/darwin/volume.h b/setter/src/darwin/volume.h index f553509..a78ee33 100644 --- a/setter/src/darwin/volume.h +++ b/setter/src/darwin/volume.h @@ -127,4 +127,112 @@ Copyright (C) 2011-2021 Natalia Portillo #define MNT_STRICTATIME 0x80000000 #endif +#ifndef VOL_CAPABILITIES_FORMAT +#define VOL_CAPABILITIES_FORMAT 0 +#endif + +#ifndef VOL_CAP_FMT_PERSISTENTOBJECTIDS +#define VOL_CAP_FMT_PERSISTENTOBJECTIDS 0x00000001 +#endif + +#ifndef VOL_CAP_FMT_SYMBOLICLINKS +#define VOL_CAP_FMT_SYMBOLICLINKS 0x00000002 +#endif + +#ifndef VOL_CAP_FMT_HARDLINKS +#define VOL_CAP_FMT_HARDLINKS 0x00000004 +#endif + +#ifndef VOL_CAP_FMT_JOURNAL +#define VOL_CAP_FMT_JOURNAL 0x00000008 +#endif + +#ifndef VOL_CAP_FMT_JOURNAL_ACTIVE +#define VOL_CAP_FMT_JOURNAL_ACTIVE 0x00000010 +#endif + +#ifndef VOL_CAP_FMT_NO_ROOT_TIMES +#define VOL_CAP_FMT_NO_ROOT_TIMES 0x00000020 +#endif + +#ifndef VOL_CAP_FMT_SPARSE_FILES +#define VOL_CAP_FMT_SPARSE_FILES 0x00000040 +#endif + +#ifndef VOL_CAP_FMT_ZERO_RUNS +#define VOL_CAP_FMT_ZERO_RUNS 0x00000080 +#endif + +#ifndef VOL_CAP_FMT_CASE_SENSITIVE +#define VOL_CAP_FMT_CASE_SENSITIVE 0x00000100 +#endif + +#ifndef VOL_CAP_FMT_CASE_PRESERVING +#define VOL_CAP_FMT_CASE_PRESERVING 0x00000200 +#endif + +#ifndef VOL_CAP_FMT_FAST_STATFS +#define VOL_CAP_FMT_FAST_STATFS 0x00000400 +#endif + +#ifndef VOL_CAP_FMT_2TB_FILESIZE +#define VOL_CAP_FMT_2TB_FILESIZE 0x00000800 +#endif + +#ifndef VOL_CAP_FMT_OPENDENYMODES +#define VOL_CAP_FMT_OPENDENYMODES 0x00001000 +#endif + +#ifndef VOL_CAP_FMT_HIDDEN_FILES +#define VOL_CAP_FMT_HIDDEN_FILES 0x00002000 +#endif + +#ifndef VOL_CAP_FMT_PATH_FROM_ID +#define VOL_CAP_FMT_PATH_FROM_ID 0x00004000 +#endif + +#ifndef VOL_CAP_FMT_NO_VOLUME_SIZES +#define VOL_CAP_FMT_NO_VOLUME_SIZES 0x00008000 +#endif + +#ifndef VOL_CAP_FMT_DECMPFS_COMPRESSION +#define VOL_CAP_FMT_DECMPFS_COMPRESSION 0x00010000 +#endif + +#ifndef VOL_CAP_FMT_64BIT_OBJECT_IDS +#define VOL_CAP_FMT_64BIT_OBJECT_IDS 0x00020000 +#endif + +#ifndef VOL_CAP_FMT_DIR_HARDLINKS +#define VOL_CAP_FMT_DIR_HARDLINKS 0x00040000 +#endif + +#ifndef VOL_CAP_FMT_DOCUMENT_ID +#define VOL_CAP_FMT_DOCUMENT_ID 0x00080000 +#endif + +#ifndef VOL_CAP_FMT_WRITE_GENERATION_COUNT +#define VOL_CAP_FMT_WRITE_GENERATION_COUNT 0x00100000 +#endif + +#ifndef VOL_CAP_FMT_NO_IMMUTABLE_FILES +#define VOL_CAP_FMT_NO_IMMUTABLE_FILES 0x00200000 +#endif + +#ifndef VOL_CAP_FMT_NO_PERMISSIONS +#define VOL_CAP_FMT_NO_PERMISSIONS 0x00400000 +#endif + +#ifndef VOL_CAP_FMT_SHARED_SPACE +#define VOL_CAP_FMT_SHARED_SPACE 0x00800000 +#endif + +#ifndef VOL_CAP_FMT_VOL_GROUPS +#define VOL_CAP_FMT_VOL_GROUPS 0x01000000 +#endif + +#ifndef VOL_CAP_FMT_SEALED +#define VOL_CAP_FMT_SEALED 0x02000000 +#endif + #endif // AARU_FSTESTER_SETTER_SRC_DARWIN_VOLUME_H_ diff --git a/setter/src/unix/volume.c b/setter/src/unix/volume.c index 5fa5772..4a178a3 100644 --- a/setter/src/unix/volume.c +++ b/setter/src/unix/volume.c @@ -175,4 +175,8 @@ void GetVolumeInfo(const char* path, size_t* clusterSize) } *clusterSize = buf.f_bsize; + +#if defined(__APPLE__) && defined(__MACH__) + DarwinVolumeAttributes(path); +#endif }