mirror of
https://github.com/ksherlock/mpw.git
synced 2025-02-19 17:30:32 +00:00
more native
This commit is contained in:
parent
8bdad6281e
commit
2aae28fedf
@ -28,6 +28,7 @@
|
|||||||
#include <sys/attr.h>
|
#include <sys/attr.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
//using MacOS::macos_error_from_errno;
|
//using MacOS::macos_error_from_errno;
|
||||||
//using MacOS::macos_error;
|
//using MacOS::macos_error;
|
||||||
@ -113,7 +114,7 @@ namespace native {
|
|||||||
|
|
||||||
rv = getxattr(path_name.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
|
rv = getxattr(path_name.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
|
||||||
if (rv == 16 || rv == 32) {
|
if (rv == 16 || rv == 32) {
|
||||||
fixup_prodos_ftype(buffer);
|
prodos_ftype_out(buffer);
|
||||||
memcpy(info, buffer, extended ? 32 : 16);
|
memcpy(info, buffer, extended ? 32 : 16);
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
@ -196,7 +197,7 @@ namespace native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
fixup_prodos_ftype(buffer);
|
prodos_ftype_out(buffer);
|
||||||
memcpy(info, buffer, extended ? 32 : 16);
|
memcpy(info, buffer, extended ? 32 : 16);
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
@ -211,6 +212,28 @@ namespace native {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macos_error set_finder_info(const std::string &path_name, const void *info, bool extended) {
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
ssize_t rv;
|
||||||
|
|
||||||
|
std::memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
if (extended) {
|
||||||
|
std::memcpy(buffer, info, 32);
|
||||||
|
} else {
|
||||||
|
get_finder_info(path_name, buffer, true);
|
||||||
|
std::memcpy(buffer, info, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
prodos_ftype_in(buffer);
|
||||||
|
rv = setxattr(path_name.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
|
||||||
|
if ( rv < 0) return macos_error_from_errno();
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
macos_error get_file_info(const std::string &path_name, file_info &fi)
|
macos_error get_file_info(const std::string &path_name, file_info &fi)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -222,9 +245,11 @@ namespace native {
|
|||||||
fi.modify_date = unix_to_mac(st.st_mtime);
|
fi.modify_date = unix_to_mac(st.st_mtime);
|
||||||
fi.backup_date = 0;
|
fi.backup_date = 0;
|
||||||
|
|
||||||
|
fi.attributes = 0;
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
fi.type = file_info::directory;
|
fi.type = file_info::directory;
|
||||||
|
fi.attributes = 1 << 4;
|
||||||
|
|
||||||
int links = st.st_nlink - 2;
|
int links = st.st_nlink - 2;
|
||||||
if (links < 0) links = 0;
|
if (links < 0) links = 0;
|
||||||
@ -253,6 +278,79 @@ namespace native {
|
|||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macos_error set_file_info(const std::string &path_name, const file_info &fi) {
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(path_name.c_str(), &st) < 0) return macos_error_from_errno();
|
||||||
|
|
||||||
|
if (S_ISREG(st.st_mode)) {
|
||||||
|
auto rv = set_finder_info(path_name, fi.finder_info);
|
||||||
|
if (rv) return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t create_date = fi.create_date ? mac_to_unix(fi.create_date) : 0;
|
||||||
|
time_t modify_date = fi.modify_date ? mac_to_unix(fi.modify_date) : 0;
|
||||||
|
time_t backup_date = fi.backup_date ? mac_to_unix(fi.backup_date) : 0;
|
||||||
|
|
||||||
|
// todo -- value of 0 == set to current date/time?
|
||||||
|
|
||||||
|
if (create_date == st.st_birthtime) create_date = 0;
|
||||||
|
if (modify_date == st.st_mtime) modify_date = 0;
|
||||||
|
|
||||||
|
// try setattr list.
|
||||||
|
int rv;
|
||||||
|
struct attrlist list;
|
||||||
|
unsigned i = 0;
|
||||||
|
timespec dates[3];
|
||||||
|
|
||||||
|
memset(&list, 0, sizeof(list));
|
||||||
|
memset(dates, 0, sizeof(dates));
|
||||||
|
|
||||||
|
list.bitmapcount = ATTR_BIT_MAP_COUNT;
|
||||||
|
list.commonattr = 0;
|
||||||
|
|
||||||
|
if (create_date)
|
||||||
|
{
|
||||||
|
dates[i++].tv_sec = create_date;
|
||||||
|
list.commonattr |= ATTR_CMN_CRTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fi.modify_date)
|
||||||
|
{
|
||||||
|
dates[i++].tv_sec = modify_date;
|
||||||
|
list.commonattr |= ATTR_CMN_MODTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backup_date)
|
||||||
|
{
|
||||||
|
dates[i++].tv_sec = backup_date;
|
||||||
|
list.commonattr |= ATTR_CMN_BKUPTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i) return noErr;
|
||||||
|
|
||||||
|
rv = setattrlist(path_name.c_str(), &list, dates, i * sizeof(timespec), 0);
|
||||||
|
|
||||||
|
|
||||||
|
if (rv < 0 && errno == ENOTSUP)
|
||||||
|
{
|
||||||
|
// try utimes.
|
||||||
|
|
||||||
|
struct timeval tv[2];
|
||||||
|
memset(tv, 0, sizeof(tv));
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
if (modify_date) {
|
||||||
|
tv[1].tv_sec = modify_date;
|
||||||
|
rv = utimes(path_name.c_str(), tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv < 0) return macos_error_from_errno();
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -76,7 +76,7 @@ namespace native {
|
|||||||
ssize_t x = read(fd, buffer, 32);
|
ssize_t x = read(fd, buffer, 32);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (x == 32 || x == 16){
|
if (x == 32 || x == 16){
|
||||||
fixup_prodos_ftype(buffer);
|
prodos_ftype_out(buffer);
|
||||||
memcpy(info, buffer, extended ? 32 : 16);
|
memcpy(info, buffer, extended ? 32 : 16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ namespace native {
|
|||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
fi.type = file_info::directory;
|
fi.type = file_info::directory;
|
||||||
|
fi.attributes = 1 << 4;
|
||||||
|
|
||||||
int links = st.st_nlink - 2;
|
int links = st.st_nlink - 2;
|
||||||
if (links < 0) links = 0;
|
if (links < 0) links = 0;
|
||||||
@ -136,4 +136,4 @@ namespace native {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "native_internal.h"
|
#include "native_internal.h"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
using namespace MacOS;
|
using namespace MacOS;
|
||||||
|
|
||||||
@ -63,18 +64,30 @@ namespace {
|
|||||||
return s.substr(pos + 1);
|
return s.substr(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned tox(unsigned x)
|
||||||
|
{
|
||||||
|
if (x >= '0' && x <= '9') return x - '0';
|
||||||
|
if (x >= 'a' && x <= 'f') return x - 'a' + 10;
|
||||||
|
if (x >= 'A' && x <= 'F') return x - 'A' + 10;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace native {
|
namespace native {
|
||||||
|
|
||||||
|
|
||||||
time_t unix_to_mac(time_t t) {
|
uint32_t unix_to_mac(time_t t) {
|
||||||
if (!t) return 0;
|
if (!t) return 0;
|
||||||
return t + epoch_adjust;
|
return t + epoch_adjust;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixup_prodos_ftype(uint8_t *buffer) {
|
time_t mac_to_unix(uint32_t t) {
|
||||||
|
if (!t) return 0;
|
||||||
|
return t - epoch_adjust;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prodos_ftype_out(uint8_t *buffer) {
|
||||||
if (memcmp(buffer + 4, "pdos", 4) == 0) {
|
if (memcmp(buffer + 4, "pdos", 4) == 0) {
|
||||||
// mpw expects 'xx ' where
|
// mpw expects 'xx ' where
|
||||||
// xx are the ascii-encode hex value of the file type.
|
// xx are the ascii-encode hex value of the file type.
|
||||||
@ -94,6 +107,22 @@ namespace native {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prodos_ftype_in(uint8_t *buffer) {
|
||||||
|
if (::memcmp(buffer + 2, " pdos", 6) == 0)
|
||||||
|
{
|
||||||
|
unsigned a = buffer[0];
|
||||||
|
unsigned b = buffer[1];
|
||||||
|
|
||||||
|
if (isxdigit(a) && isxdigit(b))
|
||||||
|
{
|
||||||
|
buffer[0] = 'p';
|
||||||
|
buffer[1] = (tox(a) << 4) | tox(b);
|
||||||
|
buffer[2] = 0;
|
||||||
|
buffer[3] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
macos_error get_finder_info(const std::string &path_name, uint32_t &ftype, uint32_t &ctype) {
|
macos_error get_finder_info(const std::string &path_name, uint32_t &ftype, uint32_t &ctype) {
|
||||||
|
|
||||||
@ -109,6 +138,24 @@ namespace native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macos_error set_finder_info(const std::string &path_name, uint32_t ftype, uint32_t ctype) {
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
std::memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
buffer[0] = ftype >> 24;
|
||||||
|
buffer[1] = ftype >> 16;
|
||||||
|
buffer[2] = ftype >> 8;
|
||||||
|
buffer[3] = ftype >> 0;
|
||||||
|
|
||||||
|
buffer[4] = ctype >> 24;
|
||||||
|
buffer[5] = ctype >> 16;
|
||||||
|
buffer[6] = ctype >> 8;
|
||||||
|
buffer[7] = ctype >> 0;
|
||||||
|
|
||||||
|
return set_finder_info(path_name, buffer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_text_file_internal(const std::string &path_name) {
|
bool is_text_file_internal(const std::string &path_name) {
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ namespace native {
|
|||||||
|
|
||||||
enum { none, file, directory } type = none;
|
enum { none, file, directory } type = none;
|
||||||
|
|
||||||
|
uint16_t attributes = 0;
|
||||||
uint32_t create_date = 0;
|
uint32_t create_date = 0;
|
||||||
uint32_t modify_date = 0;
|
uint32_t modify_date = 0;
|
||||||
uint32_t backup_date = 0;
|
uint32_t backup_date = 0;
|
||||||
@ -31,11 +32,16 @@ namespace native {
|
|||||||
};
|
};
|
||||||
|
|
||||||
macos_error get_file_info(const std::string &path_name, file_info &fi);
|
macos_error get_file_info(const std::string &path_name, file_info &fi);
|
||||||
|
macos_error set_file_info(const std::string &path_name, const file_info &fi);
|
||||||
|
|
||||||
macos_error get_finder_info(const std::string &path_name, void *buffer, bool extended = true);
|
macos_error get_finder_info(const std::string &path_name, void *buffer, bool extended = true);
|
||||||
macos_error get_finder_info(const std::string &path_name, uint32_t &ftype, uint32_t &ctype);
|
macos_error get_finder_info(const std::string &path_name, uint32_t &ftype, uint32_t &ctype);
|
||||||
|
|
||||||
|
macos_error set_finder_info(const std::string &path_name, const void *buffer, bool extended = true);
|
||||||
|
macos_error set_finder_info(const std::string &path_name, uint32_t ftype, uint32_t ctype);
|
||||||
|
|
||||||
time_t unix_to_mac(time_t t);
|
uint32_t unix_to_mac(time_t t);
|
||||||
|
time_t mac_to_unix(uint32_t t);
|
||||||
|
|
||||||
|
|
||||||
bool is_text_file(const std::string &path_name);
|
bool is_text_file(const std::string &path_name);
|
||||||
|
@ -12,7 +12,8 @@ namespace native {
|
|||||||
bool is_text_file_internal(const std::string &path_name);
|
bool is_text_file_internal(const std::string &path_name);
|
||||||
bool is_binary_file_internal(const std::string &path_name);
|
bool is_binary_file_internal(const std::string &path_name);
|
||||||
|
|
||||||
void fixup_prodos_ftype(uint8_t *buffer);
|
void prodos_ftype_in(uint8_t *buffer);
|
||||||
|
void prodos_ftype_out(uint8_t *buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user