mirror of
https://github.com/depp/syncfiles.git
synced 2024-11-29 18:49:44 +00:00
d5bfaa510a
Include paths are updated to include the directory. It seems that CodeWarrior will search for include files recursively, which means that "error.h" may resolve to the wrong file (there are two). I am unsure of the rules CodeWarrior uses to find header files. Support for older versions of Universal Interfaces has been added. The project code has been reworked after thoroughly reviewing Inside Macintosh: Files. It is not complete, but it compiles, and the behavior of the Save / Save As commands have been thought out more carefully.
94 lines
2.0 KiB
C
94 lines
2.0 KiB
C
// Copyright 2022 Dietrich Epp.
|
|
// This file is part of SyncFiles. SyncFiles is licensed under the terms of the
|
|
// Mozilla Public License, version 2.0. See LICENSE.txt for details.
|
|
#include "macos/path.h"
|
|
|
|
#include "macos/error.h"
|
|
|
|
#include <string.h>
|
|
|
|
enum {
|
|
kMaxPath = 512,
|
|
};
|
|
|
|
OSErr GetDirPath(FSSpec *spec, int *pathLength, Handle *path)
|
|
{
|
|
Handle segments; // Packed sequence of segments, Pascal strings.
|
|
int textLen; // Total length of segments, including length byte.
|
|
Handle result;
|
|
unsigned char *name;
|
|
CInfoPBRec ci;
|
|
OSErr err;
|
|
unsigned char *op;
|
|
const unsigned char *ip, *ie;
|
|
int length;
|
|
|
|
// Query target.
|
|
memset(&ci, 0, sizeof(ci));
|
|
ci.dirInfo.ioNamePtr = spec->name;
|
|
ci.dirInfo.ioVRefNum = spec->vRefNum;
|
|
ci.dirInfo.ioDrDirID = spec->parID;
|
|
err = PBGetCatInfoSync(&ci);
|
|
if (err != noErr) {
|
|
return err;
|
|
}
|
|
// FIXME: kioFlAttribDirMask
|
|
if ((ci.hFileInfo.ioFlAttrib & ioDirMask) == 0) {
|
|
return fnfErr;
|
|
}
|
|
segments = NULL;
|
|
textLen = spec->name[0] + 1;
|
|
PtrToHand(spec->name, &segments, textLen);
|
|
if (segments == NULL) {
|
|
return MemError();
|
|
}
|
|
|
|
// Add name of parent.
|
|
while (ci.dirInfo.ioDrParID != fsRtParID) {
|
|
ASSERT(textLen < kMaxPath);
|
|
SetHandleSize(segments, textLen + 256);
|
|
err = MemError();
|
|
if (err != noErr) {
|
|
goto done;
|
|
}
|
|
HLock(segments);
|
|
name = (unsigned char *)*segments + textLen;
|
|
ci.dirInfo.ioNamePtr = name;
|
|
ci.dirInfo.ioDrDirID = ci.dirInfo.ioDrParID;
|
|
ci.dirInfo.ioFDirIndex = -1;
|
|
err = PBGetCatInfoSync(&ci);
|
|
HUnlock(segments);
|
|
if (err != 0) {
|
|
goto done;
|
|
}
|
|
textLen += name[0] + 1;
|
|
}
|
|
|
|
// Copy segments into handle in reverse order.
|
|
result = NewHandle(textLen);
|
|
if (result == NULL) {
|
|
err = MemError();
|
|
goto done;
|
|
}
|
|
op = (unsigned char *)*result + textLen;
|
|
ip = (const unsigned char *)*segments;
|
|
ie = ip + textLen;
|
|
while (ip < ie) {
|
|
op--;
|
|
*op = ':';
|
|
length = *ip;
|
|
op -= length;
|
|
BlockMoveData(ip + 1, op, length);
|
|
ip += length + 1;
|
|
}
|
|
*pathLength = textLen;
|
|
*path = result;
|
|
err = 0;
|
|
|
|
done:
|
|
if (segments != NULL) {
|
|
DisposeHandle(segments);
|
|
}
|
|
return err;
|
|
}
|