mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2024-12-12 19:30:38 +00:00
update finder_info_helper.
This commit is contained in:
parent
97787b30e4
commit
ebd67dc0cc
@ -206,6 +206,12 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T _(const T t, std::error_code &ec) {
|
||||
if (t < 0) ec = std::error_code(errno, std::generic_category());
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* extended attributes functions.
|
||||
*/
|
||||
@ -293,19 +299,30 @@ namespace {
|
||||
|
||||
|
||||
|
||||
int fi_open(const std::wstring &path, int perm) {
|
||||
#if defined(_WIN32)
|
||||
std::wstring s(path);
|
||||
s.append(L":" XATTR_FINDERINFO_NAME);
|
||||
if (perm == 1) return open(s.c_str(), O_RDONLY | O_BINARY);
|
||||
else return open(s.c_str(), O_RDWR | O_CREAT | O_BINARY, 0666);
|
||||
#else
|
||||
|
||||
int fi_open(const std::string &path, bool read_only) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int fi_open(const std::string &path, int perm) {
|
||||
|
||||
#if defined(__sun__)
|
||||
if (read_only) return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDONLY);
|
||||
if (perm == 1) return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDONLY);
|
||||
else return attropen(path.c_str(), XATTR_FINDERINFO_NAME, O_RDWR | O_CREAT, 0666);
|
||||
#elif defined(_WIN32)
|
||||
std::string s(path);
|
||||
s.append(":" XATTR_FINDERINFO_NAME);
|
||||
if (read_only) return open(s.c_str(), O_RDONLY | O_BINARY);
|
||||
if (perm == 1) return open(s.c_str(), O_RDONLY | O_BINARY);
|
||||
else return open(s.c_str(), O_RDWR | O_CREAT | O_BINARY, 0666);
|
||||
#else
|
||||
|
||||
// linux needs to open as read/write to write it?
|
||||
//return open(path.c_str(), read_only ? O_RDONLY : O_RDWR);
|
||||
return open(path.c_str(), O_RDONLY);
|
||||
#endif
|
||||
}
|
||||
@ -370,10 +387,12 @@ enum {
|
||||
void afp_synchronize(struct AFP_Info *info, int trust) {
|
||||
// if ftype/auxtype is inconsistent between prodos and finder info, use
|
||||
// prodos as source of truth.
|
||||
uint16_t f;
|
||||
uint32_t a;
|
||||
if (finder_info_to_filetype(info->finder_info, &f, &a) != 0) return;
|
||||
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
||||
uint16_t f = 0;
|
||||
uint32_t a = 0;
|
||||
if (finder_info_to_filetype(info->finder_info, &f, &a)) {
|
||||
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
||||
}
|
||||
|
||||
if (trust == trust_prodos)
|
||||
file_type_to_finder_info(info->finder_info, info->prodos_file_type, info->prodos_aux_type);
|
||||
else {
|
||||
@ -400,36 +419,86 @@ finder_info_helper::~finder_info_helper() {
|
||||
if (_fd >= 0) close(_fd);
|
||||
}
|
||||
|
||||
bool finder_info_helper::open(const std::string &name, bool read_only) {
|
||||
bool finder_info_helper::open(const std::string &name, std::error_code &ec, open_mode perm) {
|
||||
|
||||
ec.clear();
|
||||
|
||||
if (_fd >= 0) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
int fd = fi_open(name, read_only);
|
||||
|
||||
if (perm < 1 || perm > 3) {
|
||||
ec = std::make_error_code(std::errc::invalid_argument);
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = _(fi_open(name, perm), ec);
|
||||
if (fd < 0) return false;
|
||||
|
||||
int ok = read(fd);
|
||||
// if write mode, it's ok if finder info doesn't exist (yet).
|
||||
if (!read_only && !ok) ok = true;
|
||||
// win32 should read even if write-only.
|
||||
bool ok = read(fd, ec);
|
||||
|
||||
if (read_only) close(fd);
|
||||
else _fd = fd;
|
||||
if (perm == read_only) {
|
||||
close(fd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
return ok;
|
||||
// write mode, so it's ok if it doesn't exist.
|
||||
if (!ok) ec.clear();
|
||||
_fd = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool finder_info_helper::read(int fd) {
|
||||
#if 0
|
||||
bool finder_info_helper::open(const filesystem::path &pathName, std::error_code &ec, open_mode perm) {
|
||||
|
||||
ec.clear();
|
||||
|
||||
if (_fd >= 0) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
|
||||
if (perm < 1 || perm > 3) {
|
||||
ec = std::make_error_code(std::errc::invalid_argument);
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = _(fi_open(pathName.native(), perm), ec);
|
||||
if (fd < 0) return false;
|
||||
|
||||
// win32 should read even if write-only.
|
||||
bool ok = read(fd, ec);
|
||||
|
||||
if (perm == read_only) {
|
||||
close(fd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
// write mode, so it's ok if it doesn't exist.
|
||||
if (!ok) ec.clear();
|
||||
_fd = fd;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool finder_info_helper::read(int fd, std::error_code &ec) {
|
||||
#if defined(_WIN32)
|
||||
int ok = fi_read(fd, &_afp, sizeof(_afp));
|
||||
int ok = _(fi_read(fd, &_afp, sizeof(_afp)), ec);
|
||||
if (ok < 0) {
|
||||
afp_init(&_afp);
|
||||
return false;
|
||||
}
|
||||
if (ok < sizeof(_afp) || !afp_verify(&_afp)) {
|
||||
ec = std::make_error_code(std::errc::illegal_byte_sequence); // close enough!
|
||||
afp_init(&_afp);
|
||||
return false;
|
||||
}
|
||||
if (!_afp.prodos_file_type && !_afp.prodos_aux_type)
|
||||
afp_synchronize(&_afp, trust_hfs);
|
||||
#else
|
||||
int ok = fi_read(fd, &_finder_info, sizeof(_finder_info));
|
||||
int ok = _(fi_read(fd, &_finder_info, sizeof(_finder_info)), ec);
|
||||
if (ok < 0) {
|
||||
memset(&_finder_info, 0, sizeof(_finder_info));
|
||||
return false;
|
||||
@ -439,27 +508,44 @@ bool finder_info_helper::read(int fd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool finder_info_helper::write(int fd) {
|
||||
bool finder_info_helper::write(int fd, std::error_code &ec) {
|
||||
#if defined(_WIN32)
|
||||
return fi_write(fd, &_afp, sizeof(_afp));
|
||||
return _(fi_write(fd, &_afp, sizeof(_afp)),ec);
|
||||
#else
|
||||
return fi_write(fd, &_finder_info, sizeof(_finder_info));
|
||||
return _(fi_write(fd, &_finder_info, sizeof(_finder_info)),ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool finder_info_helper::write() {
|
||||
return write(_fd);
|
||||
bool finder_info_helper::write(std::error_code &ec) {
|
||||
ec.clear();
|
||||
return write(_fd, ec);
|
||||
}
|
||||
|
||||
|
||||
bool finder_info_helper::write(const std::string &name) {
|
||||
int fd = fi_open(name, false);
|
||||
if (fd < 0) return false;
|
||||
bool ok = write(fd);
|
||||
bool finder_info_helper::write(const std::string &name, std::error_code &ec) {
|
||||
ec.clear();
|
||||
int fd = _(fi_open(name, write_only), ec);
|
||||
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
bool ok = write(fd, ec);
|
||||
close(fd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool finder_info_helper::write(const filesystem::path &pathName, std::error_code &ec) {
|
||||
ec.clear();
|
||||
int fd = _(fi_open(pathName.native(), write_only), ec);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
bool ok = write(fd, ec);
|
||||
close(fd);
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void finder_info_helper::set_prodos_file_type(uint16_t ftype, uint32_t atype) {
|
||||
@ -481,6 +567,15 @@ bool finder_info_helper::is_text() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool finder_info_helper::is_binary() const {
|
||||
if (is_text()) return false;
|
||||
if (_prodos_file_type || _prodos_aux_type) return true;
|
||||
|
||||
if (memcmp(_finder_info, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t finder_info_helper::file_type() const {
|
||||
uint32_t rv = 0;
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include <system_error>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#pragma pack(push, 2)
|
||||
struct AFP_Info {
|
||||
@ -22,6 +24,12 @@ class finder_info_helper {
|
||||
|
||||
public:
|
||||
|
||||
enum open_mode {
|
||||
read_only = 1,
|
||||
write_only = 2,
|
||||
read_write = 3,
|
||||
};
|
||||
|
||||
finder_info_helper();
|
||||
~finder_info_helper();
|
||||
|
||||
@ -49,10 +57,33 @@ public:
|
||||
}
|
||||
|
||||
|
||||
bool read(const std::string &fname);
|
||||
bool write(const std::string &fname);
|
||||
bool open(const std::string &fname, bool read_only = true);
|
||||
bool write();
|
||||
bool read(const std::string &fname, std::error_code &ec) {
|
||||
return open(fname, ec);
|
||||
}
|
||||
|
||||
bool write(const std::string &fname, std::error_code &ec);
|
||||
|
||||
bool open(
|
||||
const std::string &fname,
|
||||
std::error_code &ec,
|
||||
open_mode perm = read_only
|
||||
);
|
||||
|
||||
#if 0
|
||||
bool read(const filesystem::path &pathName, std::error_code &ec) {
|
||||
return open(pathName, ec);
|
||||
}
|
||||
|
||||
bool write(const filesystem::path &pathName, std::error_code &ec);
|
||||
|
||||
bool open(
|
||||
const filesystem::path &pathName,
|
||||
std::error_code &ec,
|
||||
open_mode perm = read_only
|
||||
);
|
||||
#endif
|
||||
|
||||
bool write(std::error_code &ec);
|
||||
|
||||
uint32_t creator_type() const;
|
||||
uint32_t file_type() const;
|
||||
@ -80,11 +111,12 @@ public:
|
||||
void set_creator_type(uint32_t);
|
||||
|
||||
bool is_text() const;
|
||||
bool is_binary() const;
|
||||
|
||||
private:
|
||||
|
||||
bool write(int fd);
|
||||
bool read(int fd);
|
||||
bool write(int fd, std::error_code &ec);
|
||||
bool read(int fd, std::error_code &ec);
|
||||
|
||||
int _fd = -1;
|
||||
|
||||
|
@ -9,10 +9,11 @@ int set_file_type(const std::string &path, uint16_t file_type, uint32_t aux_type
|
||||
finder_info_helper fi;
|
||||
|
||||
bool ok;
|
||||
ok = fi.open(path, false);
|
||||
std::error_code ec;
|
||||
ok = fi.open(path, ec, finder_info_helper::read_write);
|
||||
if (!ok) return -1;
|
||||
fi.set_prodos_file_type(file_type, aux_type);
|
||||
ok = fi.write();
|
||||
ok = fi.write(ec);
|
||||
if (!ok) return -1;
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user