more native

This commit is contained in:
Kelvin Sherlock 2016-07-31 15:34:41 -04:00
parent 8bdad6281e
commit 2aae28fedf
5 changed files with 163 additions and 11 deletions

View File

@ -28,6 +28,7 @@
#include <sys/attr.h>
#include <sys/xattr.h>
#include <sys/stat.h>
#include <unistd.h>
//using MacOS::macos_error_from_errno;
//using MacOS::macos_error;
@ -113,7 +114,7 @@ namespace native {
rv = getxattr(path_name.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
if (rv == 16 || rv == 32) {
fixup_prodos_ftype(buffer);
prodos_ftype_out(buffer);
memcpy(info, buffer, extended ? 32 : 16);
return noErr;
}
@ -196,7 +197,7 @@ namespace native {
}
}
fixup_prodos_ftype(buffer);
prodos_ftype_out(buffer);
memcpy(info, buffer, extended ? 32 : 16);
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)
{
struct stat st;
@ -222,9 +245,11 @@ namespace native {
fi.modify_date = unix_to_mac(st.st_mtime);
fi.backup_date = 0;
fi.attributes = 0;
if (S_ISDIR(st.st_mode)) {
fi.type = file_info::directory;
fi.attributes = 1 << 4;
int links = st.st_nlink - 2;
if (links < 0) links = 0;
@ -253,6 +278,79 @@ namespace native {
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;
}
}

View File

@ -76,7 +76,7 @@ namespace native {
ssize_t x = read(fd, buffer, 32);
close(fd);
if (x == 32 || x == 16){
fixup_prodos_ftype(buffer);
prodos_ftype_out(buffer);
memcpy(info, buffer, extended ? 32 : 16);
return 0;
}
@ -105,7 +105,7 @@ namespace native {
if (S_ISDIR(st.st_mode)) {
fi.type = file_info::directory;
fi.attributes = 1 << 4;
int links = st.st_nlink - 2;
if (links < 0) links = 0;
@ -136,4 +136,4 @@ namespace native {
}
}

View File

@ -27,6 +27,7 @@
#include "native_internal.h"
#include <cctype>
using namespace MacOS;
@ -63,18 +64,30 @@ namespace {
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 {
time_t unix_to_mac(time_t t) {
uint32_t unix_to_mac(time_t t) {
if (!t) return 0;
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) {
// mpw expects 'xx ' where
// 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) {
@ -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) {

View File

@ -15,6 +15,7 @@ namespace native {
enum { none, file, directory } type = none;
uint16_t attributes = 0;
uint32_t create_date = 0;
uint32_t modify_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 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, 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);

View File

@ -12,7 +12,8 @@ namespace native {
bool is_text_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