mirror of
https://github.com/ksherlock/mpw.git
synced 2025-02-16 12:30:53 +00:00
more native
This commit is contained in:
parent
8bdad6281e
commit
2aae28fedf
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user