Skip to content

Commit

Permalink
Mac resource forks, first version
Browse files Browse the repository at this point in the history
  • Loading branch information
autc04 committed Nov 29, 2017
1 parent c832553 commit 7e465e3
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 17 deletions.
3 changes: 2 additions & 1 deletion src/fileCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ A4(PRIVATE, OSErr, PBDeleteForD, ParmBlkPtr, pb, BOOLEAN, a,
rpathname = ROMlib_resname(pathname, filename, endname);
deletefailed = Uunlink(rpathname);
double_dir_op(pathname, rmdir_op);
if(!deletefailed || errno == ENOTDIR || errno == ENOENT)
if(!deletefailed || errno == ENOTDIR || errno == ENOENT || errno == ENOTSUP)
// ENOTSUP triggered by trying to delete ..namedfork/rsrc on Mac OS X
deletefailed = Uunlink(pathname);
if(deletefailed && ford == Directory)
{
Expand Down
130 changes: 115 additions & 15 deletions src/fileDouble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include "FileMgr.h"
#include "rsys/file.h"

#ifdef MACOSX
#include <sys/xattr.h>
#endif

#if defined(CYGWIN32)
#include "winfs.h"
#endif
Expand All @@ -17,6 +21,10 @@ int netatalk_conventions_p;
char apple_double_quote_char;
const char *apple_double_fork_prefix;
int apple_double_fork_prefix_length;
const char *resfork_suffix = "";
int resfork_suffix_length = 0;

bool native_resfork_p = true;
}

namespace Executor
Expand Down Expand Up @@ -157,7 +165,12 @@ A3(PUBLIC, OSErr, ROMlib_newresfork, char *, name, LONGINT *, fdp,
ourentries.finfo.finfo.fdCreator = 0;
}
initialize_ourdefault();
if((fd = Uopen(name, (O_BINARY | O_RDWR | O_CREAT), 0666L)) < 0 || write(fd, (char *)&ourdefault, sizeof(ourdefault)) != sizeof(ourdefault) || write(fd, (char *)&ourentries, sizeof(ourentries)) != sizeof(ourentries))
if((fd = Uopen(name, (O_BINARY | O_RDWR | O_CREAT), 0666L)) < 0
|| (!native_resfork_p &&
(write(fd, (char *)&ourdefault, sizeof(ourdefault)) != sizeof(ourdefault)
|| write(fd, (char *)&ourentries, sizeof(ourentries)) != sizeof(ourentries)))
)

{
retval = ROMlib_maperrno();
Uclose(fd);
Expand Down Expand Up @@ -253,6 +266,9 @@ A1(PUBLIC, LONGINT, ROMlib_FORKOFFSET, fcbrec *, fp) /* INTERNAL */
Single_descriptor d;
Single_ID idwanted;

if(native_resfork_p)
return 0;

if(fp->fcfd != fp->hiddenfd)
/*-->*/ return 0L;
idwanted = IDWANTED(fp);
Expand Down Expand Up @@ -287,7 +303,7 @@ A1(PUBLIC, OSErr, ROMlib_seteof, fcbrec *, fp) /* INTERNAL */
fd = fp->fcfd;
leof = Cx(fp->fcleof);
err = noErr;
if(fd == fp->hiddenfd)
if(!native_resfork_p && fd == fp->hiddenfd)
{ /* mixed file */
idwanted = IDWANTED(fp);
if(getsetentry(Get, fd, idwanted, &d, &peof))
Expand Down Expand Up @@ -386,7 +402,7 @@ A1(PUBLIC, OSErr, ROMlib_geteofostype, fcbrec *, fp) /* INTERNAL */
else
{
err = noErr;
if(fd == fp->fcfd)
if(!native_resfork_p && fd == fp->fcfd)
{ /* mixed file */
idwanted = IDWANTED(fp);
if(!getsetentry(Get, fd, idwanted, &d, NULL))
Expand All @@ -401,6 +417,28 @@ A1(PUBLIC, OSErr, ROMlib_geteofostype, fcbrec *, fp) /* INTERNAL */
fp->fcleof = fp->fcPLen = CL((int)sbuf.st_size);
if(err == noErr)
{
#ifdef MACOSX
if(native_resfork_p)
{
/* struct {
FInfo finfo;
FXInfo fxinfo;
} buffer;
if(getxattr(pathname, XATTR_FINDERINFO_NAME, &buffer, 32, 0, 0) < 0)
{
uint32 type;
if(ROMlib_creator_and_type_from_filename(fp->fcname[0], (char *)fp->fcname + 1, NULL, &type))
fp->fcbFType = CL(type);
else
fp->fcbFType = TICKX("TEXT");
}
else
fp->fcbFType = buffer.finfo.fdType;*/
fp->fcbFType = 0; /* who reads this, anyway? */
}
else
#endif
if(!getsetentry(Get, fd, Finder_Info_ID, &d, NULL) || (!getsetpiece(Get, fd, &d, (char *)&finfo, sizeof(finfo))))
{
uint32 type;
Expand Down Expand Up @@ -448,6 +486,62 @@ A8(PUBLIC, OSErr, ROMlib_hiddenbyname, GetOrSetType, gors, /* INTERNAL */
retval = ROMlib_maperrno();
else
{
#ifdef MACOSX
if(native_resfork_p)
{
struct {
FInfo finfo;
FXInfo fxinfo;
} buffer;
if(gors == Get)
{
if(getxattr(pathname, XATTR_FINDERINFO_NAME, &buffer, 32, 0, 0) < 0)
{
memset(&buffer, 0, sizeof(buffer));
}
if(finfop)
*finfop = buffer.finfo;
if(fxinfop)
*fxinfop = buffer.fxinfo;

if(datep)
{
datep->crdat = CL(UNIXTIMETOMACTIME(sbuf.st_birthtime));
datep->moddat = CL(UNIXTIMETOMACTIME(sbuf.st_mtime));
datep->accessdat = CL(UNIXTIMETOMACTIME(sbuf.st_atime));
datep->backupdat = 0;
}
if(lenp)
*lenp = CL((int)sbuf.st_size);
if(rlenp)
{
if(Ustat(rpathname, &sbuf) < 0)
*rlenp = 0;
else
*rlenp = CL((int)sbuf.st_size);
}
fs_err_hook(retval);
return retval;
}
else
{
if(getxattr(pathname, XATTR_FINDERINFO_NAME, &buffer, 32, 0, 0) < 0)
{
memset(&buffer, 0, sizeof(buffer));
}

if(finfop)
buffer.finfo = *finfop;
if(fxinfop)
buffer.fxinfo = *fxinfop;

if(setxattr(pathname, XATTR_FINDERINFO_NAME, &buffer, 32, 0, 0) < 0)
retval = ROMlib_maperrno();
fs_err_hook(retval);
return retval;
}
}
#endif
done = false;
rfd = Uopen(rpathname, O_BINARY | (gors == Set ? O_RDWR : O_RDONLY), 0);
/*
Expand Down Expand Up @@ -578,12 +672,17 @@ A3(PUBLIC, char *, ROMlib_resname, char *, pathname, /* INTERNAL */
if(pathnamesize)
{
newsize = pathnamesize + filenamesize
+ apple_double_fork_prefix_length;
+ apple_double_fork_prefix_length
+ resfork_suffix_length;
newname = (char *)malloc(newsize);
memcpy(newname, pathname, pathnamesize);
strcpy(&newname[pathnamesize], apple_double_fork_prefix);
memcpy(newname + pathnamesize + apple_double_fork_prefix_length,
filename, filenamesize);
memcpy(newname + pathnamesize + apple_double_fork_prefix_length + filenamesize - 1,
resfork_suffix, resfork_suffix_length);
newname[newsize-1] = 0;

}
else
{
Expand Down Expand Up @@ -660,31 +759,32 @@ A2(PUBLIC, char *, ROMlib_newunixfrommac, char *, ip, INTEGER, n)

void Executor::setup_resfork_format(ResForkFormat rf)
{
afpd_conventions_p = netatalk_conventions_p = false;
afpd_conventions_p = netatalk_conventions_p = native_resfork_p = false;
switch(rf)
{
case ResForkFormat::standard:
apple_double_quote_char = '%';
apple_double_fork_prefix = "%";
break;
case ResForkFormat::afpd:
apple_double_quote_char = '%';
apple_double_fork_prefix = "%";
afpd_conventions_p = true;
break;
case ResForkFormat::netatalk:
afpd_conventions_p = netatalk_conventions_p = true;
apple_double_quote_char = ':';
apple_double_fork_prefix = ".AppleDouble/";
break;
case ResForkFormat::native:
apple_double_quote_char = '%';
apple_double_fork_prefix = "";
resfork_suffix = "/..namedfork/rsrc";
native_resfork_p = true;
break;
}
if(netatalk_conventions_p)
{
apple_double_quote_char = ':';
apple_double_fork_prefix = ".AppleDouble/";
}
else
{
apple_double_quote_char = '%';
apple_double_fork_prefix = "%";
}
apple_double_fork_prefix_length = strlen(apple_double_fork_prefix);
resfork_suffix_length = strlen(resfork_suffix);
}

void Executor::report_resfork_problem()
Expand Down
2 changes: 2 additions & 0 deletions src/fileInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ A5(PUBLIC, OSErr, ROMlib_PBGetSetFInfoD, ParmBlkPtr, pb, /* INTERNAL */
((CInfoPBPtr)pb)->hFileInfo.ioFlClpSiz = CLC(512);
}
}
#if 0
if(Ustat(rpathname, &resourcesbuf) < 0)
{
pb->fileParam.ioFlRPyLen = 0;
Expand Down Expand Up @@ -514,6 +515,7 @@ A5(PUBLIC, OSErr, ROMlib_PBGetSetFInfoD, ParmBlkPtr, pb, /* INTERNAL */
sizeof(((CInfoPBPtr)pb)->hFileInfo.ioFlXFndrInfo));
}
else
#endif
{
if((err = ROMlib_hiddenbyname(Get, pathname, rpathname, &dateinfo,
&finfo, &fxinfo, &pb->fileParam.ioFlLgLen,
Expand Down
6 changes: 5 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ capable of color.",
opt_no_arg, "" },
{ "afpd", "use afpd conventions for AppleDouble files (implies -netatalk)",
opt_no_arg, "" },
{ "rsrc", "use native resource forks on Mac OS X",
opt_no_arg, "" },

#if defined(MSDOS)
{
Expand Down Expand Up @@ -1612,9 +1614,11 @@ int main(int argc, char **argv)
setup_resfork_format(ResForkFormat::netatalk);
else if(opt_val(common_db, "afpd", NULL))
setup_resfork_format(ResForkFormat::afpd);
else if(opt_val(common_db, "rsrc", NULL))
setup_resfork_format(ResForkFormat::native);
else
setup_resfork_format(ResForkFormat::standard);

substitute_fonts_p = !opt_val(common_db, "cities", NULL);

if(opt_val(common_db, "offset", NULL))
Expand Down

0 comments on commit 7e465e3

Please sign in to comment.