mirror of
https://github.com/ksherlock/afp.git
synced 2024-06-06 05:29:30 +00:00
update resource fork w/ updates
This commit is contained in:
parent
a09131a479
commit
359c97d531
|
@ -18,6 +18,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE_
|
#ifdef __APPLE_
|
||||||
|
@ -58,16 +59,24 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
#ifdef MSVC
|
||||||
|
#define AFP_ERROR_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND
|
||||||
|
#define remap_os_error(x) x
|
||||||
|
#else
|
||||||
|
#define AFP_ERROR_FILE_NOT_FOUND ENOENT
|
||||||
|
extern "C" int remap_os_error(unsigned long);
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOL _(BOOL x, std::error_code &ec) {
|
BOOL _(BOOL x, std::error_code &ec) {
|
||||||
if (!x) ec = std::error_code(GetLastError(), std::system_category());
|
if (!x) ec = std::error_code(remap_os_error(GetLastError()), std::system_category());
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE _(HANDLE x, std::error_code &ec) {
|
HANDLE _(HANDLE x, std::error_code &ec) {
|
||||||
if (x == INVALID_HANDLE_VALUE)
|
if (x == INVALID_HANDLE_VALUE)
|
||||||
ec = std::error_code(GetLastError(), std::system_category());
|
ec = std::error_code(remap_os_error(GetLastError()), std::system_category());
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +116,35 @@ namespace {
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD GetFileAttributesX(const std::string &path) {
|
||||||
|
return GetFileAttributesA(path.c_str());
|
||||||
|
}
|
||||||
|
DWORD GetFileAttributesX(const std::wstring &path) {
|
||||||
|
return GetFileAttributesW(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class StringType>
|
||||||
|
bool regular_file(const StringType &path, std::error_code &ec) {
|
||||||
|
|
||||||
|
// make sure this isn't a directory.
|
||||||
|
DWORD st = GetFileAttributesX(path);
|
||||||
|
if (st == INVALID_FILE_ATTRIBUTES) {
|
||||||
|
ec = std::error_code(remap_os_error(GetLastError()), std::system_category());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (st & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
ec = std::make_error_code(std::errc::is_a_directory);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (st & FILE_ATTRIBUTE_DEVICE) {
|
||||||
|
ec = std::make_error_code(std::errc::invalid_seek);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -115,6 +153,31 @@ namespace {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool regular_file(int fd, std::error_code &ec) {
|
||||||
|
struct stat st;
|
||||||
|
if (_(::fstat(fd, &st), ec) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (S_ISREG(st.st_mode)) return true;
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
ec = std::make_error_code(std::errc::is_a_directory);
|
||||||
|
} else {
|
||||||
|
ec = std::make_error_code(std::errc::invalid_seek); // ESPIPE.
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* opens a file read-only and verifies it's a regular file */
|
||||||
|
int openX(const std::string &path, std::error_code &ec) {
|
||||||
|
int fd = _(::open(path.c_str(), O_RDONLY | O_NONBLOCK), ec);
|
||||||
|
if (fd >= 0 && !regular_file(fd, ec)) {
|
||||||
|
::close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -150,6 +213,8 @@ namespace afp {
|
||||||
ec.clear();
|
ec.clear();
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
if (!regular_file(path, ec)) return false;
|
||||||
|
|
||||||
std::string s(path);
|
std::string s(path);
|
||||||
s += ":" XATTR_RESOURCEFORK_NAME;
|
s += ":" XATTR_RESOURCEFORK_NAME;
|
||||||
|
|
||||||
|
@ -158,7 +223,7 @@ namespace afp {
|
||||||
_fd = CreateFileX(s, mode, ec);
|
_fd = CreateFileX(s, mode, ec);
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
if (ec.value() == ERROR_FILE_NOT_FOUND)
|
if (ec.value() == AFP_ERROR_FILE_NOT_FOUND)
|
||||||
ec = std::make_error_code(std::errc::no_message_available);
|
ec = std::make_error_code(std::errc::no_message_available);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +235,8 @@ namespace afp {
|
||||||
ec.clear();
|
ec.clear();
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
if (!regular_file(path, ec)) return false;
|
||||||
|
|
||||||
std::wstring s(path);
|
std::wstring s(path);
|
||||||
s += L":" XATTR_RESOURCEFORK_NAME;
|
s += L":" XATTR_RESOURCEFORK_NAME;
|
||||||
|
|
||||||
|
@ -178,7 +245,7 @@ namespace afp {
|
||||||
_fd = CreateFileX(s, mode, ec);
|
_fd = CreateFileX(s, mode, ec);
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
if (ec.value() == ERROR_FILE_NOT_FOUND)
|
if (ec.value() == AFP_ERROR_FILE_NOT_FOUND)
|
||||||
ec = std::make_error_code(std::errc::no_message_available);
|
ec = std::make_error_code(std::errc::no_message_available);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +332,8 @@ namespace afp {
|
||||||
case write_only umode = O_WRONLY | O_CREAT; break;
|
case write_only umode = O_WRONLY | O_CREAT; break;
|
||||||
case read_write: umode = O_RDWR | O_CREAT; break;
|
case read_write: umode = O_RDWR | O_CREAT; break;
|
||||||
}
|
}
|
||||||
int fd = _(::open(path.c_str(), O_RDONLY),ec);
|
|
||||||
|
int fd = openX(path, ec);
|
||||||
if (ec) return false;
|
if (ec) return false;
|
||||||
|
|
||||||
_fd = ::openat(path.c_str(), XATTR_RESOURCEFORK_NAME, umode | O_XATTR, 0666);
|
_fd = ::openat(path.c_str(), XATTR_RESOURCEFORK_NAME, umode | O_XATTR, 0666);
|
||||||
|
@ -292,7 +360,7 @@ namespace afp {
|
||||||
std::string s(path);
|
std::string s(path);
|
||||||
s += _PATH_RSRCFORKSPEC;
|
s += _PATH_RSRCFORKSPEC;
|
||||||
|
|
||||||
int fd = _(open(path.c_str(), O_RDONLY), ec);
|
int fd = openX(path, ec);
|
||||||
if (ec) return false;
|
if (ec) return false;
|
||||||
|
|
||||||
int umode = 0;
|
int umode = 0;
|
||||||
|
@ -384,10 +452,12 @@ namespace afp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool resource_fork::open(const std::string &s, open_mode mode, std::error_code &ec) {
|
|
||||||
|
bool resource_fork::open(const std::string &path, open_mode mode, std::error_code &ec) {
|
||||||
close();
|
close();
|
||||||
ec.clear();
|
ec.clear();
|
||||||
_fd = _(::open(s.c_str(), O_RDONLY), ec);
|
|
||||||
|
int fd = openX(path, ec);
|
||||||
if (ec) return false;
|
if (ec) return false;
|
||||||
|
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
@ -395,7 +465,6 @@ namespace afp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t resource_fork::size(std::error_code &ec) {
|
size_t resource_fork::size(std::error_code &ec) {
|
||||||
ec.clear();
|
ec.clear();
|
||||||
auto rv = _(::size_xattr(_fd, XATTR_RESOURCEFORK_NAME), ec);
|
auto rv = _(::size_xattr(_fd, XATTR_RESOURCEFORK_NAME), ec);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user