#define MODE_TO_DT(mode) (modetodirtype[((mode) & S_IFMT) >> 12])
-static int cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, int allow_system_files, u_long hint, int wantrsrc,
+static int cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, int allow_system_files, u_int32_t hint, int wantrsrc,
struct cat_desc *descp, struct cat_attr *attrp, struct cat_fork *forkp, cnid_t *desc_cnid);
static int cat_lookupmangled(struct hfsmount *hfsmp, struct cat_desc *descp, int wantrsrc,
static int cat_findposition(const CatalogKey *ckp, const CatalogRecord *crp,
struct position_state *state);
-static int resolvelinkid(struct hfsmount *hfsmp, u_long linkref, ino_t *ino);
+static int resolvelinkid(struct hfsmount *hfsmp, u_int32_t linkref, ino_t *ino);
static int getkey(struct hfsmount *hfsmp, cnid_t cnid, CatalogKey * key);
static int catrec_update(const CatalogKey *ckp, CatalogRecord *crp, struct update_state *state);
-static int builddesc(const HFSPlusCatalogKey *key, cnid_t cnid, u_long hint, u_long encoding,
+static int builddesc(const HFSPlusCatalogKey *key, cnid_t cnid, u_int32_t hint, u_int32_t encoding,
int isdir, struct cat_desc *descp);
static void getbsdattr(struct hfsmount *hfsmp, const struct HFSPlusCatalogFile *crp, struct cat_attr * attrp);
-static void promotekey(struct hfsmount *hfsmp, const HFSCatalogKey *hfskey, HFSPlusCatalogKey *keyp, u_long *encoding);
+static void promotekey(struct hfsmount *hfsmp, const HFSCatalogKey *hfskey, HFSPlusCatalogKey *keyp, u_int32_t *encoding);
static void promotefork(struct hfsmount *hfsmp, const struct HFSCatalogFile *file, int resource, struct cat_fork * forkp);
static void promoteattr(struct hfsmount *hfsmp, const CatalogRecord *dataPtr, struct HFSPlusCatalogFile *crp);
static cnid_t getcnid(const CatalogRecord *crp);
-static u_long getencoding(const CatalogRecord *crp);
+static u_int32_t getencoding(const CatalogRecord *crp);
static cnid_t getparentcnid(const CatalogRecord *recp);
static int isadir(const CatalogRecord *crp);
{
int std_hfs = HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord;
HFSPlusCatalogKey * pluskey = NULL;
- u_long encoding;
+ u_int32_t encoding;
if (std_hfs) {
MALLOC(pluskey, HFSPlusCatalogKey *, sizeof(HFSPlusCatalogKey), M_TEMP, M_WAITOK);
}
if (std_hfs) {
HFSPlusCatalogKey * pluskey = NULL;
- u_long encoding;
+ u_int32_t encoding;
MALLOC(pluskey, HFSPlusCatalogKey *, sizeof(HFSPlusCatalogKey), M_TEMP, M_WAITOK);
promotekey(hfsmp, &keyp->hfs, pluskey, &encoding);
case kHFSFileThreadRecord:
case kHFSFolderThreadRecord:
keyp = (CatalogKey *)((char *)&recp->hfsThread.reserved + 6);
+
+ /* check for NULL name */
+ if (keyp->hfs.nodeName[0] == 0) {
+ result = ENOENT;
+ goto exit;
+ }
+
keyp->hfs.keyLength = kHFSCatalogKeyMinimumLength + keyp->hfs.nodeName[0];
break;
case kHFSPlusFileThreadRecord:
case kHFSPlusFolderThreadRecord:
keyp = (CatalogKey *)&recp->hfsPlusThread.reserved;
+
+ /* check for NULL name */
+ if (keyp->hfsPlus.nodeName.length == 0) {
+ result = ENOENT;
+ goto exit;
+ }
+
keyp->hfsPlus.keyLength = kHFSPlusCatalogKeyMinimumLength +
(keyp->hfsPlus.nodeName.length * 2);
break;
* the key in the thread matches the key in the record.
*/
if (cnid != dcnid) {
- printf("Requested cnid (%d / %08x) != dcnid (%d / %08x)\n", cnid, cnid, dcnid, dcnid);
+ printf("hfs: cat_idlookup: Requested cnid (%d / %08x) != dcnid (%d / %08x)\n", cnid, cnid, dcnid, dcnid);
result = ENOENT;
}
}
cnid_t fileID;
u_int32_t prefixlen;
int result;
+ int extlen1, extlen2;
if (wantrsrc)
return (ENOENT);
bcmp(outdescp->cd_nameptr, descp->cd_nameptr, prefixlen-6) != 0)
goto falsematch;
+ extlen1 = CountFilenameExtensionChars(descp->cd_nameptr, descp->cd_namelen);
+ extlen2 = CountFilenameExtensionChars(outdescp->cd_nameptr, outdescp->cd_namelen);
+ if (extlen1 != extlen2)
+ goto falsematch;
+
+ if (bcmp(outdescp->cd_nameptr + (outdescp->cd_namelen - extlen2),
+ descp->cd_nameptr + (descp->cd_namelen - extlen1),
+ extlen1) != 0)
+ goto falsematch;
+
return (0);
falsematch:
* cat_lookupbykey - lookup a catalog node using a cnode key
*/
static int
-cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, int allow_system_files, u_long hint, int wantrsrc,
+cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, int allow_system_files, u_int32_t hint, int wantrsrc,
struct cat_desc *descp, struct cat_attr *attrp, struct cat_fork *forkp, cnid_t *desc_cnid)
{
struct BTreeIterator * iterator;
u_int16_t datasize;
int result;
int std_hfs;
- u_long ilink = 0;
+ u_int32_t ilink = 0;
cnid_t cnid = 0;
- u_long encoding = 0;
+ u_int32_t encoding = 0;
std_hfs = (HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord);
u_int32_t datalen;
int std_hfs;
int result = 0;
- u_long encoding = kTextEncodingMacRoman;
+ u_int32_t encoding = kTextEncodingMacRoman;
int modeformat;
modeformat = attrp->ca_mode & S_IFMT;
int directory = from_cdp->cd_flags & CD_ISDIR;
int is_dirlink = 0;
int std_hfs;
- u_long encoding = 0;
+ u_int32_t encoding = 0;
vcb = HFSTOVCB(hfsmp);
fcb = GetFileControlBlock(vcb->catalogRefNum);
int err;
err = BTInsertRecord(fcb, from_iterator, &btdata, datasize);
if (err) {
- printf("cat_create: could not undo (BTInsert = %d)", err);
+ printf("hfs: cat_create: could not undo (BTInsert = %d)", err);
hfs_mark_volume_inconsistent(hfsmp);
result = err;
goto exit;
int err;
err = BTDeleteRecord(fcb, to_iterator);
if (err) {
- printf("cat_create: could not undo (BTDelete = %d)", err);
+ printf("hfs: cat_create: could not undo (BTDelete = %d)", err);
hfs_mark_volume_inconsistent(hfsmp);
result = err;
goto exit;
/* Save the real encoding hint in the Finder Info (field 4). */
if (directory && from_cdp->cd_cnid == kHFSRootFolderID) {
- u_long realhint;
+ u_int32_t realhint;
realhint = hfs_pickencoding(pluskey->nodeName.unicode, pluskey->nodeName.length);
vcb->vcbFndrInfo[4] = SET_HFS_TEXT_ENCODING(realhint);
dir = (struct HFSPlusCatalogFolder *)crp;
/* Do a quick sanity check */
if (dir->folderID != attrp->ca_fileid) {
- printf("catrec_update: id %d != %d\n", dir->folderID, attrp->ca_fileid);
+ printf("hfs: catrec_update: id %d != %d\n", dir->folderID, attrp->ca_fileid);
return (btNotFound);
}
dir->flags = attrp->ca_recflags;
if ((file->resourceFork.extents[0].startBlock != 0) &&
(file->resourceFork.extents[0].startBlock ==
file->dataFork.extents[0].startBlock)) {
- panic("catrec_update: rsrc fork == data fork");
+ panic("hfs: catrec_update: rsrc fork == data fork");
}
/* Synchronize the lock state */
/* Update the bit in corresponding cnode, if any, in the hash.
* If the cnode has the bit already set, stop the traversal.
*/
- retval = hfs_chash_set_childlinkbit(hfsmp->hfs_raw_dev, cnid);
+ retval = hfs_chash_set_childlinkbit(hfsmp, cnid);
if (retval == 0) {
break;
}
break;
}
if ((result = getkey(hfsmp, cnid, (CatalogKey *)keyp))) {
- printf("cat_check_link_ancestry: getkey for %u failed\n", cnid);
+ printf("hfs: cat_check_link_ancestry: getkey for %u failed\n", cnid);
invalid = 1; /* On errors, assume an invalid parent */
break;
}
if ((result = BTSearchRecord(fcb, ip, &btdata, NULL, NULL))) {
- printf("cat_check_link_ancestry: cannot find %u\n", cnid);
+ printf("hfs: cat_check_link_ancestry: cannot find %u\n", cnid);
invalid = 1; /* On errors, assume an invalid parent */
break;
}
HFSPlusCatalogFile *file;
if (crp->recordType != kHFSPlusFileRecord) {
- printf("updatelink_callback: unexpected rec type %d\n", crp->recordType);
+ printf("hfs: updatelink_callback: unexpected rec type %d\n", crp->recordType);
return (btNotFound);
}
file->hl_nextLinkID = state->nextlinkid;
}
} else {
- printf("updatelink_callback: file %d isn't a chain\n", file->fileID);
+ printf("hfs: updatelink_callback: file %d isn't a chain\n", file->fileID);
}
return (0);
}
result = BTUpdateRecord(fcb, iterator, (IterateCallBackProcPtr)updatelink_callback, &state);
(void) BTFlushPath(fcb);
} else {
- printf("cat_updatelink: couldn't resolve cnid %d\n", linkfileid);
+ printf("hfs: cat_updatelink: couldn't resolve cnid %d\n", linkfileid);
}
return MacToVFSError(result);
}
iterator->hint.nodeNum = 0;
if ((result = getkey(hfsmp, linkfileid, (CatalogKey *)&iterator->key))) {
- printf("cat_lookuplinkbyid: getkey for %d failed %d\n", linkfileid, result);
+ printf("hfs: cat_lookuplinkbyid: getkey for %d failed %d\n", linkfileid, result);
goto exit;
}
BDINIT(btdata, &file);
if ((result = BTSearchRecord(fcb, iterator, &btdata, NULL, NULL))) {
- printf("cat_lookuplinkbyid: cannot find %d\n", linkfileid);
+ printf("hfs: cat_lookuplinkbyid: cannot find %d\n", linkfileid);
goto exit;
}
/* The prev/next chain is only valid when kHFSHasLinkChainMask is set. */
HFSPlusForkData *rsrcforkp;
u_int32_t nextCNID;
u_int32_t datalen;
- u_long encoding;
+ u_int32_t encoding;
int thread_inserted = 0;
int alias_allocated = 0;
int result = 0;
result = buildkey(hfsmp, descp, &bto->key, 0);
if (result) {
- printf("cat_createlink: err %d from buildkey\n", result);
+ printf("hfs: cat_createlink: err %d from buildkey\n", result);
goto exit;
}
exit:
if (result) {
if (thread_inserted) {
- printf("cat_createlink: err %d from BTInsertRecord\n", MacToVFSError(result));
+ printf("hfs: cat_createlink: err %d from BTInsertRecord\n", MacToVFSError(result));
buildthreadkey(nextCNID, 0, (CatalogKey *)&bto->iterator.key);
if (BTDeleteRecord(fcb, &bto->iterator)) {
if (state->stdhfs) {
struct HFSPlusCatalogFile cnoderec;
HFSPlusCatalogKey * pluskey;
- u_long encoding;
+ u_int32_t encoding;
promoteattr(hfsmp, rec, &cnoderec);
getbsdattr(hfsmp, &cnoderec, &cep->ce_attr);
/* Hard link information collected during cat_getdirentries. */
struct linkinfo {
- u_long link_ref;
+ u_int32_t link_ref;
user_addr_t dirent_addr;
};
typedef struct linkinfo linkinfo_t;
int hide = 0;
u_int8_t type = DT_UNKNOWN;
u_int8_t is_mangled = 0;
+ u_int8_t is_link = 0;
u_int8_t *nameptr;
user_addr_t uiobase = USER_ADDR_NULL;
size_t namelen = 0;
} else {
ilinkref = crp->hfsPlusFile.hl_linkReference;
}
+ is_link =1;
} else if ((SWAP_BE32(crp->hfsPlusFile.userInfo.fdType) == kHFSAliasType) &&
(SWAP_BE32(crp->hfsPlusFile.userInfo.fdCreator) == kHFSAliasCreator) &&
(crp->hfsPlusFile.flags & kHFSHasLinkChainMask) &&
type = DT_DIR;
/* A directory's link ref is always inode's file id. */
cnid = crp->hfsPlusFile.hl_linkReference;
+ is_link = 1;
}
/* Hide the journal files */
if ((curID == kHFSRootFolderID) &&
/* Check result returned from encoding the filename to utf8 */
if (result == ENAMETOOLONG) {
+ /*
+ * If we were looking at a catalog record for a hardlink (not the inode),
+ * then we want to use its link ID as opposed to the inode ID for
+ * a mangled name. For all other cases, they are the same. Note that
+ * due to the way directory hardlinks are implemented, the actual link
+ * is going to be counted as a file record, so we can catch both
+ * with is_link.
+ */
+ cnid_t linkid = cnid;
+ if (is_link) {
+ linkid = crp->hfsPlusFile.fileID;
+ }
+
result = ConvertUnicodeToUTF8Mangled(cnp->ustr.length * sizeof(UniChar),
cnp->ustr.unicode, maxnamelen + 1,
- (ByteCount*)&namelen, nameptr, cnid);
+ (ByteCount*)&namelen, nameptr, linkid);
is_mangled = 1;
}
}
uiobase = uio_curriovbase(state->cbs_uio);
}
/* If this entry won't fit then we're done */
- if ((uiosize > uio_resid(state->cbs_uio)) ||
+ if ((uiosize > (user_size_t)uio_resid(state->cbs_uio)) ||
(ilinkref != 0 && state->cbs_nlinks == state->cbs_maxlinks)) {
return (0); /* stop */
}
uioaddr = (caddr_t) &catent;
/* If this entry won't fit then we're done */
- if (uiosize > uio_resid(state->cbs_uio)) {
+ if (uiosize > (user_size_t)uio_resid(state->cbs_uio)) {
return (0); /* stop */
}
* Post process any hard links to get the real file id.
*/
if (state.cbs_nlinks > 0) {
- u_int32_t fileid = 0;
+ ino_t fileid = 0;
user_addr_t address;
int i;
++state->count;
break;
default:
- printf("cat_findposition: invalid record type %d in dir %d\n",
+ printf("hfs: cat_findposition: invalid record type %d in dir %d\n",
crp->recordType, curID);
state->error = EINVAL;
return (0); /* stop */
hfskey.parentID = key->parentID;
hfskey.nodeName[0] = 0;
if (key->nodeName.length > 0) {
- if (unicode_to_hfs(HFSTOVCB(hfsmp),
+ int res;
+ if ((res = unicode_to_hfs(HFSTOVCB(hfsmp),
key->nodeName.length * 2,
key->nodeName.unicode,
- &hfskey.nodeName[0], retry) != 0) {
- return (EINVAL);
+ &hfskey.nodeName[0], retry)) != 0) {
+ if (res != ENAMETOOLONG)
+ res = EINVAL;
+
+ return res;
}
hfskey.keyLength += hfskey.nodeName[0];
}
*/
__private_extern__
int
-cat_resolvelink(struct hfsmount *hfsmp, u_long linkref, int isdirlink, struct HFSPlusCatalogFile *recp)
+cat_resolvelink(struct hfsmount *hfsmp, u_int32_t linkref, int isdirlink, struct HFSPlusCatalogFile *recp)
{
FSBufferDescriptor btdata;
struct BTreeIterator *iterator;
if (recp->hl_linkCount == 0)
recp->hl_linkCount = 2;
} else {
- printf("HFS resolvelink: can't find %s\n", inodename);
+ printf("hfs: cat_resolvelink: can't find %s\n", inodename);
}
FREE(iterator, M_TEMP);
* Resolve hard link reference to obtain the inode number.
*/
static int
-resolvelinkid(struct hfsmount *hfsmp, u_long linkref, ino_t *ino)
+resolvelinkid(struct hfsmount *hfsmp, u_int32_t linkref, ino_t *ino)
{
struct HFSPlusCatalogFile record;
int error;
* builddesc - build a cnode descriptor from an HFS+ key
*/
static int
-builddesc(const HFSPlusCatalogKey *key, cnid_t cnid, u_long hint, u_long encoding,
+builddesc(const HFSPlusCatalogKey *key, cnid_t cnid, u_int32_t hint, u_int32_t encoding,
int isdir, struct cat_desc *descp)
{
int result = 0;
*/
static void
promotekey(struct hfsmount *hfsmp, const HFSCatalogKey *hfskey,
- HFSPlusCatalogKey *keyp, u_long *encoding)
+ HFSPlusCatalogKey *keyp, u_int32_t *encoding)
{
hfs_to_unicode_func_t hfs_get_unicode = hfsmp->hfs_get_unicode;
u_int32_t uniCount;
int resource, struct cat_fork * forkp)
{
struct HFSPlusExtentDescriptor *xp;
- u_long blocksize = HFSTOVCB(hfsmp)->blockSize;
+ u_int32_t blocksize = HFSTOVCB(hfsmp)->blockSize;
bzero(forkp, sizeof(*forkp));
xp = &forkp->cf_extents[0];
static void
promoteattr(struct hfsmount *hfsmp, const CatalogRecord *dataPtr, struct HFSPlusCatalogFile *crp)
{
- u_long blocksize = HFSTOVCB(hfsmp)->blockSize;
+ u_int32_t blocksize = HFSTOVCB(hfsmp)->blockSize;
if (dataPtr->recordType == kHFSFolderRecord) {
const struct HFSCatalogFolder * folder;
/*
* Extract the text encoding from a catalog node record.
*/
-static u_long
+static u_int32_t
getencoding(const CatalogRecord *crp)
{
- u_long encoding;
+ u_int32_t encoding;
if (crp->recordType == kHFSPlusFolderRecord)
encoding = crp->hfsPlusFolder.textEncoding;