- /* If there's anything left, use it instead of the volume's name */
- if (mpnamelen > 0) {
- name = mpname;
- namelen = mpnamelen;
- };
- };
-
- attrlength = namelen + 1;
- ((struct attrreference *)(*attrbufptrptr))->attr_dataoffset = (char *)(*varbufptrptr) - (char *)(*attrbufptrptr);
- ((struct attrreference *)(*attrbufptrptr))->attr_length = attrlength;
- (void) strncpy((unsigned char *)(*varbufptrptr), name, attrlength);
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)(*varbufptrptr) += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)(*attrbufptrptr));
-}
-
-
-
-void PackVolCommonAttributes(struct attrlist *alist,
- struct vnode *root_vp,
- struct hfsCatalogInfo *root_catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- struct hfsnode *root_hp = VTOH(root_vp);
- struct mount *mp = VTOVFS(root_vp);
- struct hfsmount *hfsmp = VTOHFS(root_vp);
- ExtendedVCB *vcb = HFSTOVCB(hfsmp);
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- if ((a = alist->commonattr) != 0) {
- if (a & ATTR_CMN_NAME) {
- PackObjectName(root_vp, H_NAME(root_hp), root_hp->h_meta->h_namelen, &attrbufptr, &varbufptr);
- };
- if (a & ATTR_CMN_DEVID) *((dev_t *)attrbufptr)++ = hfsmp->hfs_raw_dev;
- if (a & ATTR_CMN_FSID) {
- *((fsid_t *)attrbufptr) = mp->mnt_stat.f_fsid;
- ++((fsid_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJTYPE) *((fsobj_type_t *)attrbufptr)++ = 0;
- if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = VT_HFS;
- if (a & ATTR_CMN_OBJID) {
- ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJPERMANENTID) {
- ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_PAROBJID) {
- ((fsobj_id_t *)attrbufptr)->fid_objno = 0;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- VCB_LOCK(vcb);
- if (a & ATTR_CMN_SCRIPT) *((text_encoding_t *)attrbufptr)++ = vcb->volumeNameEncodingHint;
- /* NOTE: all VCB dates are in Mac OS time */
- if (a & ATTR_CMN_CRTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbCrDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_MODTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbLsMod);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_CHGTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbLsMod);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_ACCTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbLsMod);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_BKUPTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbVolBkUp);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (&vcb->vcbFndrInfo, attrbufptr, sizeof(vcb->vcbFndrInfo));
- (char *)attrbufptr += sizeof(vcb->vcbFndrInfo);
- };
- VCB_UNLOCK(vcb);
- if (a & ATTR_CMN_OWNERID) {
- if (mp->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((uid_t *)attrbufptr)++ =
- (VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid;
- } else {
- *((uid_t *)attrbufptr)++ =
- (root_hp->h_meta->h_uid == UNKNOWNUID) ? console_user : root_hp->h_meta->h_uid;
- };
- };
- if (a & ATTR_CMN_GRPID) {
- if (mp->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((gid_t *)attrbufptr)++ = VTOHFS(root_vp)->hfs_gid;
- } else {
- *((gid_t *)attrbufptr)++ = root_hp->h_meta->h_gid;
- };
- };
- if (a & ATTR_CMN_ACCESSMASK) *((u_long *)attrbufptr)++ = (u_long)root_hp->h_meta->h_mode;
- if (a & ATTR_CMN_NAMEDATTRCOUNT) *((u_long *)attrbufptr)++ = 0; /* XXX PPD TBC */
- if (a & ATTR_CMN_NAMEDATTRLIST) {
- attrlength = 0;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = 0;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_CMN_FLAGS) *((u_long *)attrbufptr)++ = root_hp->h_meta->h_pflags;
- if (a & ATTR_CMN_USERACCESS) {
- if (mp->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid,
- VTOHFS(root_vp)->hfs_gid,
- root_hp->h_meta->h_mode,
- VTOVFS(root_vp),
- current_proc()->p_ucred,
- current_proc());
- } else {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((root_hp->h_meta->h_uid == UNKNOWNUID) ? console_user : root_hp->h_meta->h_uid,
- root_hp->h_meta->h_gid,
- root_hp->h_meta->h_mode,
- VTOVFS(root_vp),
- current_proc()->p_ucred,
- current_proc());
- };
- };
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-
-
-void PackVolAttributeBlock(struct attrlist *alist,
- struct vnode *root_vp,
- struct hfsCatalogInfo *root_catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- struct mount *mp = VTOVFS(root_vp);
- struct hfsmount *hfsmp = VTOHFS(root_vp);
- ExtendedVCB *vcb = HFSTOVCB(hfsmp);
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- if ((a = alist->volattr) != 0) {
- VCB_LOCK(vcb);
- if (a & ATTR_VOL_FSTYPE) *((u_long *)attrbufptr)++ = (u_long)mp->mnt_vfc->vfc_typenum;
- if (a & ATTR_VOL_SIGNATURE) *((u_long *)attrbufptr)++ = (u_long)vcb->vcbSigWord;
- if (a & ATTR_VOL_SIZE) *((off_t *)attrbufptr)++ = (off_t)vcb->totalBlocks * (off_t)vcb->blockSize;
- if (a & ATTR_VOL_SPACEFREE) *((off_t *)attrbufptr)++ = (off_t)vcb->freeBlocks * (off_t)vcb->blockSize;
- if (a & ATTR_VOL_SPACEAVAIL) *((off_t *)attrbufptr)++ = (off_t)vcb->freeBlocks * (off_t)vcb->blockSize;
- if (a & ATTR_VOL_MINALLOCATION) *((off_t *)attrbufptr)++ = (off_t)vcb->blockSize;
- if (a & ATTR_VOL_ALLOCATIONCLUMP) *((off_t *)attrbufptr)++ = (off_t)(vcb->vcbClpSiz);
- if (a & ATTR_VOL_IOBLOCKSIZE) *((u_long *)attrbufptr)++ = (u_long)hfsmp->hfs_logBlockSize;
- if (a & ATTR_VOL_OBJCOUNT) *((u_long *)attrbufptr)++ = (u_long)vcb->vcbFilCnt + (u_long)vcb->vcbDirCnt;
- if (a & ATTR_VOL_FILECOUNT) *((u_long *)attrbufptr)++ = (u_long)vcb->vcbFilCnt;
- if (a & ATTR_VOL_DIRCOUNT) *((u_long *)attrbufptr)++ = (u_long)vcb->vcbDirCnt;
- if (a & ATTR_VOL_MAXOBJCOUNT) *((u_long *)attrbufptr)++ = 0xFFFFFFFF;
- if (a & ATTR_VOL_MOUNTPOINT) {
- ((struct attrreference *)attrbufptr)->attr_dataoffset = (char *)varbufptr - (char *)attrbufptr;
- ((struct attrreference *)attrbufptr)->attr_length = strlen(mp->mnt_stat.f_mntonname) + 1;
- attrlength = ((struct attrreference *)attrbufptr)->attr_length;
- attrlength = attrlength + ((4 - (attrlength & 3)) & 3); /* round up to the next 4-byte boundary: */
- (void) bcopy(mp->mnt_stat.f_mntonname, varbufptr, attrlength);
-
- /* Advance beyond the space just allocated: */
- (char *)varbufptr += attrlength;
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_VOL_NAME) {
- ((struct attrreference *)attrbufptr)->attr_dataoffset = (char *)varbufptr - (char *)attrbufptr;
- ((struct attrreference *)attrbufptr)->attr_length = VTOH(root_vp)->h_meta->h_namelen + 1;
- attrlength = ((struct attrreference *)attrbufptr)->attr_length;
- attrlength = attrlength + ((4 - (attrlength & 3)) & 3); /* round up to the next 4-byte boundary: */
- bcopy(H_NAME(VTOH(root_vp)), varbufptr, attrlength);
-
- /* Advance beyond the space just allocated: */
- (char *)varbufptr += attrlength;
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_VOL_MOUNTFLAGS) *((u_long *)attrbufptr)++ = (u_long)mp->mnt_flag;
- if (a & ATTR_VOL_MOUNTEDDEVICE) {
- ((struct attrreference *)attrbufptr)->attr_dataoffset = (char *)varbufptr - (char *)attrbufptr;
- ((struct attrreference *)attrbufptr)->attr_length = strlen(mp->mnt_stat.f_mntfromname) + 1;
- attrlength = ((struct attrreference *)attrbufptr)->attr_length;
- attrlength = attrlength + ((4 - (attrlength & 3)) & 3); /* round up to the next 4-byte boundary: */
- (void) bcopy(mp->mnt_stat.f_mntfromname, varbufptr, attrlength);
-
- /* Advance beyond the space just allocated: */
- (char *)varbufptr += attrlength;
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_VOL_ENCODINGSUSED) *((unsigned long long *)attrbufptr)++ = (unsigned long long)vcb->encodingsBitmap;
- if (a & ATTR_VOL_CAPABILITIES) {
- if (vcb->vcbSigWord == kHFSPlusSigWord) {
- ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_FORMAT] =
- VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_SYMBOLICLINKS | VOL_CAP_FMT_HARDLINKS;
- } else { /* Plain HFS */
- ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_FORMAT] =
- VOL_CAP_FMT_PERSISTENTOBJECTIDS;
- }
- ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_INTERFACES] =
- VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT | VOL_CAP_INT_READDIRATTR;
- ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
- ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
-
- ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_FORMAT] =
- VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_SYMBOLICLINKS | VOL_CAP_FMT_HARDLINKS;
- ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_INTERFACES] =
- VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT | VOL_CAP_INT_READDIRATTR;
- ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_RESERVED1] = 0;
- ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_RESERVED2] = 0;
-
- ++((vol_capabilities_attr_t *)attrbufptr);
- };
- if (a & ATTR_VOL_ATTRIBUTES) {
- ((vol_attributes_attr_t *)attrbufptr)->validattr.commonattr = ATTR_CMN_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->validattr.volattr = ATTR_VOL_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->validattr.dirattr = ATTR_DIR_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->validattr.fileattr = ATTR_FILE_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->validattr.forkattr = ATTR_FORK_VALIDMASK;
-
- ((vol_attributes_attr_t *)attrbufptr)->nativeattr.commonattr = ATTR_CMN_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->nativeattr.volattr = ATTR_VOL_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->nativeattr.dirattr = ATTR_DIR_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->nativeattr.fileattr = ATTR_FILE_VALIDMASK;
- ((vol_attributes_attr_t *)attrbufptr)->nativeattr.forkattr = ATTR_FORK_VALIDMASK;
-
- ++((vol_attributes_attr_t *)attrbufptr);
- };
- VCB_UNLOCK(vcb);
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-
-
-
-void PackVolumeInfo(struct attrlist *alist,
- struct vnode *root_vp,
- struct hfsCatalogInfo *root_catinfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
-
- PackVolCommonAttributes(alist, root_vp, root_catinfo, attrbufptrptr, varbufptrptr);
- PackVolAttributeBlock(alist, root_vp, root_catinfo, attrbufptrptr, varbufptrptr);
-};
-
-// Pack the common attribute contents of an objects hfsCatalogInfo
-void PackCommonCatalogInfoAttributeBlock(struct attrlist *alist,
- struct vnode *root_vp,
- struct hfsCatalogInfo *catalogInfo,
- void **attrbufptrptr,
- void **varbufptrptr )
-{
- struct hfsnode *hp;
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
- Boolean isHFSPlus;
-
- hp = VTOH(root_vp);
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
- isHFSPlus = (VTOVCB(root_vp)->vcbSigWord == kHFSPlusSigWord);
-
- if ((a = alist->commonattr) != 0)
- {
- if (a & ATTR_CMN_NAME)
- {
- attrlength = strlen(catalogInfo->nodeData.cnm_nameptr) + 1;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = (char *)varbufptr - (char *)attrbufptr;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
- (void) strncpy((unsigned char *)varbufptr,
- catalogInfo->nodeData.cnm_nameptr, attrlength);
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_CMN_DEVID) *((dev_t *)attrbufptr)++ = H_DEV(hp);
- if (a & ATTR_CMN_FSID) {
- *((fsid_t *)attrbufptr) = VTOVFS(root_vp)->mnt_stat.f_fsid;
- ++((fsid_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJTYPE)
- {
- switch (catalogInfo->nodeData.cnd_type) {
- case kCatalogFolderNode:
- *((fsobj_type_t *)attrbufptr)++ = VDIR;
- break;
-
- case kCatalogFileNode:
- /* Files in an HFS+ catalog can represent many things (regular files, symlinks, block/character devices, ...) */
- if ((HTOVCB(hp)->vcbSigWord == kHFSPlusSigWord) &&
- (catalogInfo->nodeData.cnd_mode & IFMT)) {
- *((fsobj_type_t *)attrbufptr)++ =
- IFTOVT((mode_t)catalogInfo->nodeData.cnd_mode);
- } else {
- *((fsobj_type_t *)attrbufptr)++ = VREG;
- };
- break;
-
- default:
- *((fsobj_type_t *)attrbufptr)++ = VNON;
- break;
- };
- }
- if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = root_vp->v_tag;
- if (a & ATTR_CMN_OBJID) {
- u_int32_t cnid;
-
- /* For hard links use the link's cnid */
- if (catalogInfo->nodeData.cnd_iNodeNumCopy != 0)
- cnid = catalogInfo->nodeData.cnd_linkCNID;
- else
- cnid = catalogInfo->nodeData.cnd_nodeID;
- ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJPERMANENTID) {
- u_int32_t cnid;
-
- /* For hard links use the link's cnid */
- if (catalogInfo->nodeData.cnd_iNodeNumCopy != 0)
- cnid = catalogInfo->nodeData.cnd_linkCNID;
- else
- cnid = catalogInfo->nodeData.cnd_nodeID;
- ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_PAROBJID)
- {
- ((fsobj_id_t *)attrbufptr)->fid_objno = catalogInfo->nodeData.cnm_parID;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_SCRIPT)
- {
- if (HTOVCB(hp)->vcbSigWord == kHFSPlusSigWord) {
- *((text_encoding_t *)attrbufptr)++ = catalogInfo->nodeData.cnd_textEncoding;
- } else {
- *((text_encoding_t *)attrbufptr)++ = VTOHFS(root_vp)->hfs_encoding;
- }
- };
- if (a & ATTR_CMN_CRTIME)
- {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(catalogInfo->nodeData.cnd_createDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_MODTIME)
- {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(catalogInfo->nodeData.cnd_contentModDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_CHGTIME)
- {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(catalogInfo->nodeData.cnd_attributeModDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_ACCTIME)
- {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(catalogInfo->nodeData.cnd_accessDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_BKUPTIME)
- {
- ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(catalogInfo->nodeData.cnd_backupDate);
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_FNDRINFO)
- {
- bcopy (&catalogInfo->nodeData.cnd_finderInfo, attrbufptr, sizeof(catalogInfo->nodeData.cnd_finderInfo));
- (char *)attrbufptr += sizeof(catalogInfo->nodeData.cnd_finderInfo);
- };
- if (a & ATTR_CMN_OWNERID) {
- if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
- ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
- *((uid_t *)attrbufptr)++ =
- (VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid;
- } else {
- *((uid_t *)attrbufptr)++ =
- (catalogInfo->nodeData.cnd_ownerID == UNKNOWNUID) ? console_user : catalogInfo->nodeData.cnd_ownerID;
- };
- }
- if (a & ATTR_CMN_GRPID) {
- if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
- ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
- *((gid_t *)attrbufptr)++ = VTOHFS(root_vp)->hfs_gid;
- } else {
- *((gid_t *)attrbufptr)++ = catalogInfo->nodeData.cnd_groupID;
- };
- }
- if (a & ATTR_CMN_ACCESSMASK) {
- if (((catalogInfo->nodeData.cnd_mode & IFMT) == 0)
-#if OVERRIDE_UNKNOWN_PERMISSIONS
- || (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS)
-#endif
- ) {
- switch (catalogInfo->nodeData.cnd_type) {
- case kCatalogFileNode:
- /* Files in an HFS+ catalog can represent many things (regular files, symlinks, block/character devices, ...) */
- *((u_long *)attrbufptr)++ = (u_long)(IFREG | (ACCESSPERMS & (u_long)(VTOHFS(root_vp)->hfs_file_mask)));
- break;
-
- case kCatalogFolderNode:
- *((u_long *)attrbufptr)++ = (u_long)(IFDIR | (ACCESSPERMS & (u_long)(VTOHFS(root_vp)->hfs_dir_mask)));
- break;
-
- default:
- *((u_long *)attrbufptr)++ = (u_long)((catalogInfo->nodeData.cnd_mode & IFMT) |
- VTOHFS(root_vp)->hfs_dir_mask);
- };
- } else {
- *((u_long *)attrbufptr)++ =
- (u_long)catalogInfo->nodeData.cnd_mode;
- };
- }
- if (a & ATTR_CMN_NAMEDATTRCOUNT) *((u_long *)attrbufptr)++ = 0; /* XXX PPD TBC */
- if (a & ATTR_CMN_NAMEDATTRLIST)
- {
- attrlength = 0;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = 0;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_CMN_FLAGS) {
- u_long flags;
-
- if (catalogInfo->nodeData.cnd_mode & IFMT)
- flags = catalogInfo->nodeData.cnd_ownerFlags |
- catalogInfo->nodeData.cnd_adminFlags << 16;
- else
- flags = 0;
-
- if (catalogInfo->nodeData.cnd_type == kCatalogFileNode) {
- if (catalogInfo->nodeData.cnd_flags & kHFSFileLockedMask)
- flags |= UF_IMMUTABLE;
- else
- flags &= ~UF_IMMUTABLE;
- };
- *((u_long *)attrbufptr)++ = flags;
- };
- if (a & ATTR_CMN_USERACCESS) {
- if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
- ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid,
- VTOHFS(root_vp)->hfs_gid,
-#if OVERRIDE_UNKNOWN_PERMISSIONS
- (catalogInfo->nodeData.cnd_type == kCatalogFileNode) ? VTOHFS(root_vp)->hfs_file_mask : VTOHFS(root_vp)->hfs_dir_mask,
-#else
- (catalogInfo->nodeData.cnd_mode & IFMT) ?
- (u_long)catalogInfo->nodeData.cnd_mode :
- ((catalogInfo->nodeData.cnd_type == kCatalogFileNode) ?
- VTOHFS(root_vp)->hfs_file_mask :
- VTOHFS(root_vp)->hfs_dir_mask),
-#endif
- VTOVFS(root_vp),
- current_proc()->p_ucred,
- current_proc());
- } else {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((catalogInfo->nodeData.cnd_ownerID == UNKNOWNUID) ? console_user : catalogInfo->nodeData.cnd_ownerID,
- catalogInfo->nodeData.cnd_groupID,
- (mode_t)catalogInfo->nodeData.cnd_mode,
- VTOVFS(root_vp),
- current_proc()->p_ucred,
- current_proc());
- };
- };
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-
-void PackCommonAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- struct hfsnode *hp;
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- hp = VTOH(vp);
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- if ((a = alist->commonattr) != 0) {
- if (a & ATTR_CMN_NAME) {
- PackObjectName(vp, H_NAME(hp), hp->h_meta->h_namelen, &attrbufptr, &varbufptr);
- };
- if (a & ATTR_CMN_DEVID) *((dev_t *)attrbufptr)++ = H_DEV(hp);
- if (a & ATTR_CMN_FSID) {
- *((fsid_t *)attrbufptr) = VTOVFS(vp)->mnt_stat.f_fsid;
- ++((fsid_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJTYPE) *((fsobj_type_t *)attrbufptr)++ = vp->v_type;
- if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = vp->v_tag;
- if (a & ATTR_CMN_OBJID) {
- u_int32_t cnid;
-
- /* For hard links use the link's cnid */
- if (hp->h_meta->h_metaflags & IN_DATANODE)
- cnid = catInfo->nodeData.cnd_linkCNID;
- else
- cnid = H_FILEID(hp);
- ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_OBJPERMANENTID) {
- u_int32_t cnid;
-
- /* For hard links use the link's cnid */
- if (hp->h_meta->h_metaflags & IN_DATANODE)
- cnid = catInfo->nodeData.cnd_linkCNID;
- else
- cnid = H_FILEID(hp);
- ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_PAROBJID) {
- ((fsobj_id_t *)attrbufptr)->fid_objno = H_DIRID(hp);
- ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
- ++((fsobj_id_t *)attrbufptr);
- };
- if (a & ATTR_CMN_SCRIPT)
- {
- if (HTOVCB(hp)->vcbSigWord == kHFSPlusSigWord) {
- *((text_encoding_t *)attrbufptr)++ = catInfo->nodeData.cnd_textEncoding;
- } else {
- *((text_encoding_t *)attrbufptr)++ = VTOHFS(vp)->hfs_encoding;
- }
- };
- if (a & ATTR_CMN_CRTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = hp->h_meta->h_crtime;
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_MODTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = hp->h_meta->h_mtime;
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_CHGTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = hp->h_meta->h_ctime;
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_ACCTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = hp->h_meta->h_atime;
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_BKUPTIME) {
- ((struct timespec *)attrbufptr)->tv_sec = hp->h_meta->h_butime;
- ((struct timespec *)attrbufptr)->tv_nsec = 0;
- ++((struct timespec *)attrbufptr);
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (&catInfo->nodeData.cnd_finderInfo, attrbufptr, sizeof(catInfo->nodeData.cnd_finderInfo));
- (char *)attrbufptr += sizeof(catInfo->nodeData.cnd_finderInfo);
- };
- if (a & ATTR_CMN_OWNERID) {
- if (VTOVFS(vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((uid_t *)attrbufptr)++ =
- (VTOHFS(vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(vp)->hfs_uid;
- } else {
- *((uid_t *)attrbufptr)++ =
- (hp->h_meta->h_uid == UNKNOWNUID) ? console_user : hp->h_meta->h_uid;
- }
- };
- if (a & ATTR_CMN_GRPID) {
- if (VTOVFS(vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((gid_t *)attrbufptr)++ = VTOHFS(vp)->hfs_gid;
- } else {
- *((gid_t *)attrbufptr)++ = hp->h_meta->h_gid;
- };
- };
- if (a & ATTR_CMN_ACCESSMASK) *((u_long *)attrbufptr)++ = (u_long)hp->h_meta->h_mode;
- if (a & ATTR_CMN_NAMEDATTRCOUNT) *((u_long *)attrbufptr)++ = 0; /* XXX PPD TBC */
- if (a & ATTR_CMN_NAMEDATTRLIST) {
- attrlength = 0;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = 0;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_CMN_FLAGS) *((u_long *)attrbufptr)++ = hp->h_meta->h_pflags;
- if (a & ATTR_CMN_USERACCESS) {
- if (VTOVFS(vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((VTOHFS(vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(vp)->hfs_uid,
- VTOHFS(vp)->hfs_gid,
- hp->h_meta->h_mode,
- VTOVFS(vp),
- current_proc()->p_ucred,
- current_proc());
- } else {
- *((u_long *)attrbufptr)++ =
- DerivePermissionSummary((hp->h_meta->h_uid == UNKNOWNUID) ? console_user : hp->h_meta->h_uid,
- hp->h_meta->h_gid,
- hp->h_meta->h_mode,
- VTOVFS(vp),
- current_proc()->p_ucred,
- current_proc());
- };
- };
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-
-// Pack the directory attributes given hfsCatalogInfo
-void PackCatalogInfoDirAttributeBlock( struct attrlist *alist, struct vnode *vp,
- struct hfsCatalogInfo *catInfo, void **attrbufptrptr, void **varbufptrptr )
-{
- void *attrbufptr;
- attrgroup_t a;
- u_long valence;
-
- attrbufptr = *attrbufptrptr;
- a = alist->dirattr;
-
- if ( (catInfo->nodeData.cnd_type == kCatalogFolderNode) && (a != 0) ) {
- valence = catInfo->nodeData.cnd_valence;
- if ((catInfo->nodeData.cnm_parID == kRootParID) &&
- (VTOHFS(vp)->hfs_private_metadata_dir != 0)) {
- --valence; /* hide private dir */
- }
- /* The 'link count' is faked */
- if (a & ATTR_DIR_LINKCOUNT)
- *((u_long *)attrbufptr)++ = 2 + valence;
- if (a & ATTR_DIR_ENTRYCOUNT)
- *((u_long *)attrbufptr)++ = valence;
- if (a & ATTR_DIR_MOUNTSTATUS)
- *((u_long *)attrbufptr)++ = 0;
- };
-
- *attrbufptrptr = attrbufptr;
-}
-
-
-void PackDirAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- attrgroup_t a;
- u_long valence;
-
- attrbufptr = *attrbufptrptr;
-
- a = alist->dirattr;
- if ((vp->v_type == VDIR) && (a != 0)) {
- valence = catInfo->nodeData.cnd_valence;
- if ((catInfo->nodeData.cnm_parID == kRootParID) &&
- (VTOHFS(vp)->hfs_private_metadata_dir != 0)) {
- --valence; /* hide private dir */
- }
-
- /* The 'link count' is faked */
- if (a & ATTR_DIR_LINKCOUNT)
- *((u_long *)attrbufptr)++ = 2 + valence;
- if (a & ATTR_DIR_ENTRYCOUNT)
- *((u_long *)attrbufptr)++ = valence;
- if (a & ATTR_DIR_MOUNTSTATUS) {
- if (vp->v_mountedhere) {
- *((u_long *)attrbufptr)++ = DIR_MNTSTATUS_MNTPOINT;
- } else {
- *((u_long *)attrbufptr)++ = 0;
- };
- };
- };
-
- *attrbufptrptr = attrbufptr;
-}
-
-
-
-// Pack the file attributes from the hfsCatalogInfo for the file.
-void PackCatalogInfoFileAttributeBlock( struct attrlist *alist, struct vnode *root_vp, struct hfsCatalogInfo *catInfo, void **attrbufptrptr, void **varbufptrptr )
-{
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
- ExtendedVCB *vcb = VTOVCB(root_vp);
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- a = alist->fileattr;
- if ( (catInfo->nodeData.cnd_type == kCatalogFileNode) && (a != 0) )
- {
-#if HFS_HARDLINKS
- if (a & ATTR_FILE_LINKCOUNT) {
- u_long linkcnt = catInfo->nodeData.cnd_linkCount;
-
- if (linkcnt < 1)
- linkcnt = 1;
- *((u_long *)attrbufptr)++ = linkcnt;
- }
-#else
- if (a & ATTR_FILE_LINKCOUNT) *((u_long *)attrbufptr)++ = 1;
-#endif
- if (a & ATTR_FILE_TOTALSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_datafork.logicalSize +
- (off_t)catInfo->nodeData.cnd_rsrcfork.logicalSize;
- }
- if (a & ATTR_FILE_ALLOCSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_datafork.totalBlocks * (off_t)vcb->blockSize) +
- (off_t)((off_t)catInfo->nodeData.cnd_rsrcfork.totalBlocks * (off_t)vcb->blockSize);
- }
- if (a & ATTR_FILE_IOBLOCKSIZE) {
- *((u_long *)attrbufptr)++ = (u_long)(VTOHFS(root_vp)->hfs_logBlockSize);
- }
- if (a & ATTR_FILE_CLUMPSIZE) {
- *((u_long *)attrbufptr)++ = vcb->vcbClpSiz;
- }
- if (a & ATTR_FILE_DEVTYPE) {
- u_long rawdev;
- u_short filetype;
-
- filetype = (catInfo->nodeData.cnd_mode & IFMT);
- if (filetype == IFCHR || filetype == IFBLK)
- rawdev = (u_long)catInfo->nodeData.cnd_rawDevice;
- else
- rawdev = 0;
-
- *((u_long *)attrbufptr)++ = rawdev;
- }
- if (a & ATTR_FILE_FILETYPE) {
- *((u_long *)attrbufptr)++ = 0; /* XXX PPD */
- }
- if (a & ATTR_FILE_FORKCOUNT) {
- *((u_long *)attrbufptr)++ = 2; /* XXX PPD */
- }
- if (a & ATTR_FILE_FORKLIST) {
- attrlength = 0;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = 0;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (a & ATTR_FILE_DATALENGTH) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_datafork.logicalSize;
- }
- if (a & ATTR_FILE_DATAALLOCSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_datafork.totalBlocks * (off_t)vcb->blockSize);
- }
- if (a & ATTR_FILE_DATAEXTENTS) {
- bcopy(&catInfo->nodeData.cnd_datafork.extents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- if (a & ATTR_FILE_RSRCLENGTH) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_rsrcfork.logicalSize;
- }
- if (a & ATTR_FILE_RSRCALLOCSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_rsrcfork.totalBlocks * (off_t)vcb->blockSize);
- }
- if (a & ATTR_FILE_RSRCEXTENTS) {
- bcopy(&catInfo->nodeData.cnd_rsrcfork.extents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-
-void PackFileAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- struct hfsnode *hp = VTOH(vp);
- FCB *fcb = HTOFCB(hp);
- ExtendedVCB *vcb = HTOVCB(hp);
- Boolean isHFSPlus = (vcb->vcbSigWord == kHFSPlusSigWord);
- void *attrbufptr = *attrbufptrptr;
- void *varbufptr = *varbufptrptr;
- attrgroup_t a = alist->fileattr;
- u_long attrlength;
-
- if (a != 0) {
-#if HFS_HARDLINKS
- if (a & ATTR_FILE_LINKCOUNT) {
- u_long linkcnt = catInfo->nodeData.cnd_linkCount;
-
- if (linkcnt < 1)
- linkcnt = 1;
- *((u_long *)attrbufptr)++ = linkcnt;
- }
-#else
- if (a & ATTR_FILE_LINKCOUNT) *((u_long *)attrbufptr)++ = 1;
-#endif
- if (a & ATTR_FILE_TOTALSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_datafork.logicalSize +
- (off_t)catInfo->nodeData.cnd_rsrcfork.logicalSize;
- }
- if (a & ATTR_FILE_ALLOCSIZE) {
- switch (H_FORKTYPE(hp)) {
- case kDataFork:
- *((off_t *)attrbufptr)++ =
- (off_t)fcb->fcbPLen +
- (off_t)((off_t)catInfo->nodeData.cnd_rsrcfork.totalBlocks * (off_t)vcb->blockSize);
- break;
- case kRsrcFork:
- *((off_t *)attrbufptr)++ =
- (off_t)fcb->fcbPLen +
- (off_t)((off_t)catInfo->nodeData.cnd_datafork.totalBlocks * (off_t)vcb->blockSize);
- break;
- default:
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_datafork.totalBlocks * (off_t)vcb->blockSize) +
- (off_t)((off_t)catInfo->nodeData.cnd_rsrcfork.totalBlocks * (off_t)vcb->blockSize);
- };
- };
- if (a & ATTR_FILE_IOBLOCKSIZE) *((u_long *)attrbufptr)++ = GetLogicalBlockSize(vp);
- if (a & ATTR_FILE_CLUMPSIZE) *((u_long *)attrbufptr)++ = fcb->fcbClmpSize;
- if (a & ATTR_FILE_DEVTYPE) {
- u_long rawdev;
-
- if ((vp->v_type == VBLK) || (vp->v_type == VCHR))
- rawdev = (u_long)catInfo->nodeData.cnd_rawDevice;
- else
- rawdev = 0;
- *((u_long *)attrbufptr)++ = rawdev;
- }
- if (a & ATTR_FILE_FILETYPE) *((u_long *)attrbufptr)++ = 0; /* XXX PPD */
- if (a & ATTR_FILE_FORKCOUNT) *((u_long *)attrbufptr)++ = 2; /* XXX PPD */
- if (a & ATTR_FILE_FORKLIST) {
- attrlength = 0;
- ((struct attrreference *)attrbufptr)->attr_dataoffset = 0;
- ((struct attrreference *)attrbufptr)->attr_length = attrlength;
-
- /* Advance beyond the space just allocated and round up to the next 4-byte boundary: */
- (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
- ++((struct attrreference *)attrbufptr);
- };
- if (H_FORKTYPE(hp) == kDataFork) {
- if (a & ATTR_FILE_DATALENGTH)
- *((off_t *)attrbufptr)++ = fcb->fcbEOF;
- if (a & ATTR_FILE_DATAALLOCSIZE) *((off_t *)attrbufptr)++ = fcb->fcbPLen;
- if (a & ATTR_FILE_DATAEXTENTS) {
- bcopy ( fcb->fcbExtents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- } else {
- if (a & ATTR_FILE_DATALENGTH) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_datafork.logicalSize;
- }
- if (a & ATTR_FILE_DATAALLOCSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_datafork.totalBlocks * (off_t)vcb->blockSize);
- }
- if (a & ATTR_FILE_DATAEXTENTS) {
- bcopy(&catInfo->nodeData.cnd_datafork.extents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- };
- if (H_FORKTYPE(hp) == kRsrcFork) {
- if (a & ATTR_FILE_RSRCLENGTH)
- *((off_t *)attrbufptr)++ = fcb->fcbEOF;
- if (a & ATTR_FILE_RSRCALLOCSIZE) *((off_t *)attrbufptr)++ = fcb->fcbPLen;
- if (a & ATTR_FILE_RSRCEXTENTS) {
- bcopy ( fcb->fcbExtents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- } else {
- if (a & ATTR_FILE_RSRCLENGTH) {
- *((off_t *)attrbufptr)++ =
- (off_t)catInfo->nodeData.cnd_rsrcfork.logicalSize;
- }
- if (a & ATTR_FILE_RSRCALLOCSIZE) {
- *((off_t *)attrbufptr)++ =
- (off_t)((off_t)catInfo->nodeData.cnd_rsrcfork.totalBlocks * (off_t)vcb->blockSize);
- }
- if (a & ATTR_FILE_RSRCEXTENTS) {
- bcopy(&catInfo->nodeData.cnd_rsrcfork.extents, attrbufptr, sizeof(extentrecord));
- (char *)attrbufptr += sizeof(extentrecord) + ((4 - (sizeof(extentrecord) & 3)) & 3);
- };
- };
- };
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-
-#if 0
-void PackForkAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- /* XXX PPD TBC */
-}
-#endif
-
-
-// This routine takes catInfo, and alist, as inputs and packs it into an attribute block.
-void PackCatalogInfoAttributeBlock ( struct attrlist *alist, struct vnode *root_vp, struct hfsCatalogInfo *catInfo, void **attrbufptrptr, void **varbufptrptr)
-{
- //XXX Preflight that alist only contains bits with fields in catInfo
-
- PackCommonCatalogInfoAttributeBlock( alist, root_vp, catInfo, attrbufptrptr, varbufptrptr );
-
- switch ( catInfo->nodeData.cnd_type )
- {
- case kCatalogFolderNode:
- PackCatalogInfoDirAttributeBlock( alist, root_vp, catInfo, attrbufptrptr, varbufptrptr );
- break;
-
- case kCatalogFileNode:
- PackCatalogInfoFileAttributeBlock( alist, root_vp, catInfo, attrbufptrptr, varbufptrptr );
- break;
-
- default: /* Without this the compiler complains about VNON,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD and VSTR not being handled... */
- /* XXX PPD - Panic? */
- break;
- }
-}
-
-
-
-void PackAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr)
-{
- if (alist->volattr != 0) {
- DBG_ASSERT((vp->v_flag & VROOT) != 0);
- PackVolumeInfo(alist,vp, catInfo, attrbufptrptr, varbufptrptr);
- } else {
- PackCommonAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
-
- switch (vp->v_type) {
- case VDIR:
- PackDirAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- case VREG:
- case VLNK:
- PackFileAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- /* Without this the compiler complains about VNON,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD and VSTR
- not being handled...
- */
- default:
- /* XXX PPD - Panic? */
- break;
- };
- };
-};
-
-
-
-void UnpackVolumeAttributeBlock(struct attrlist *alist,
- struct vnode *root_vp,
- ExtendedVCB *vcb,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr = *attrbufptrptr;
- attrgroup_t a;
-
- if ((alist->commonattr == 0) && (alist->volattr == 0)) {
- return; /* Get out without dirtying the VCB */
- };
-
- VCB_LOCK(vcb);
-
- a = alist->commonattr;
-
- if (a & ATTR_CMN_SCRIPT) {
- vcb->volumeNameEncodingHint = (u_int32_t)*(((text_encoding_t *)attrbufptr)++);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_SCRIPT;
-#endif
- };
- if (a & ATTR_CMN_CRTIME) {
- vcb->vcbCrDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- /* Need to update the local time also */
- vcb->localCreateDate = UTCToLocal(vcb->vcbCrDate);
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CRTIME;
-#endif
- };
- if (a & ATTR_CMN_MODTIME) {
- vcb->vcbLsMod = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_MODTIME;
-#endif
- };
- if (a & ATTR_CMN_BKUPTIME) {
- vcb->vcbVolBkUp = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_BKUPTIME;
-#endif
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (attrbufptr, &vcb->vcbFndrInfo, sizeof(vcb->vcbFndrInfo));
- (char *)attrbufptr += sizeof(vcb->vcbFndrInfo);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FNDRINFO;
-#endif
- };
-
- DBG_ASSERT(a == 0); /* All common attributes for volumes must've been handled by now... */
-
- a = alist->volattr & ~ATTR_VOL_INFO;
- if (a & ATTR_VOL_NAME) {
- copystr(((char *)attrbufptr) + *((u_long *)attrbufptr), vcb->vcbVN, sizeof(vcb->vcbVN), NULL);
- (char *)attrbufptr += sizeof(struct attrreference);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_VOL_NAME;
-#endif
- };
-
- DBG_ASSERT(a == 0); /* All common attributes for volumes must've been handled by now... */
-
- vcb->vcbFlags |= 0xFF00; // Mark the VCB dirty
-
- VCB_UNLOCK(vcb);
-}
-
-
-void UnpackCommonAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- struct hfsnode *hp = VTOH(vp);
- void *attrbufptr;
- attrgroup_t a;
-
- attrbufptr = *attrbufptrptr;
-
- DBG_ASSERT(catInfo != NULL);
-
- a = alist->commonattr;
- if (a & ATTR_CMN_SCRIPT) {
- catInfo->nodeData.cnd_textEncoding = (u_int32_t)*((text_encoding_t *)attrbufptr)++;
- UpdateVolumeEncodings(VTOVCB(vp), catInfo->nodeData.cnd_textEncoding); /* Update the volume encoding */
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_SCRIPT;
-#endif
- };
- if (a & ATTR_CMN_CRTIME) {
- catInfo->nodeData.cnd_createDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_crtime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CRTIME;
-#endif
- };
- if (a & ATTR_CMN_MODTIME) {
- catInfo->nodeData.cnd_contentModDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_mtime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_UPDATE;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_MODTIME;
-#endif
- };
- if (a & ATTR_CMN_CHGTIME) {
- catInfo->nodeData.cnd_attributeModDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_ctime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_CHANGE;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CHGTIME;
-#endif
- };
- if (a & ATTR_CMN_ACCTIME) {
- catInfo->nodeData.cnd_accessDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_atime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_ACCESS;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_ACCTIME;
-#endif
- };
- if (a & ATTR_CMN_BKUPTIME) {
- catInfo->nodeData.cnd_backupDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_butime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_BKUPTIME;
-#endif
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (attrbufptr, &catInfo->nodeData.cnd_finderInfo, sizeof(catInfo->nodeData.cnd_finderInfo));
- (char *)attrbufptr += sizeof(catInfo->nodeData.cnd_finderInfo);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FNDRINFO;
-#endif
- };
- if (a & ATTR_CMN_OWNERID) {
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- u_int32_t uid = (u_int32_t)*((uid_t *)attrbufptr)++;
- if (uid != (uid_t)VNOVAL)
- hp->h_meta->h_uid = uid; /* catalog will get updated by hfs_chown() */
- }
- else {
- ((uid_t *)attrbufptr)++;
- }
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_OWNERID;
-#endif
- };
- if (a & ATTR_CMN_GRPID) {
- u_int32_t gid = (u_int32_t)*((gid_t *)attrbufptr)++;
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- if (gid != (gid_t)VNOVAL)
- hp->h_meta->h_gid = gid; /* catalog will get updated by hfs_chown() */
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_GRPID;
-#endif
- };
- if (a & ATTR_CMN_ACCESSMASK) {
- u_int16_t mode = (u_int16_t)*((u_long *)attrbufptr)++;
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- if (mode != (mode_t)VNOVAL) {
- hp->h_meta->h_mode &= ~ALLPERMS;
- hp->h_meta->h_mode |= (mode & ALLPERMS); /* catalog will get updated by hfs_chmod() */
- }
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_ACCESSMASK;
-#endif
- };
- if (a & ATTR_CMN_FLAGS) {
- u_long flags = *((u_long *)attrbufptr)++;
- /* Flags are settable only on HFS+ volumes. A special exception is made for the IMMUTABLE
- flags (SF_IMMUTABLE and UF_IMMUTABLE), which can be set on HFS volumes as well: */
- if ((VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) ||
- ((VTOVCB(vp)->vcbSigWord == kHFSSigWord) && ((flags & ~IMMUTABLE) == 0))) {
- if (flags != (u_long)VNOVAL) {
- hp->h_meta->h_pflags = flags; /* catalog will get updated by hfs_chflags */
- };
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FLAGS;
-#endif
- };
-
-#if HFS_DIAGNOSTIC
- if (a != 0) {
- DEBUG_BREAK_MSG(("UnpackCommonAttributes: unhandled bit: 0x%08X\n", a));
- };
-#endif
-
- *attrbufptrptr = attrbufptr;
-// *varbufptrptr = varbufptr;
-}
-
-
-
-#if 0
-void UnpackDirAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-#if 0
-void UnpackFileAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-#if 0
-void UnpackForkAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-void UnpackAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
-
-
- if (alist->volattr != 0) {
- UnpackVolumeAttributeBlock(alist, vp, VTOVCB(vp), attrbufptrptr, varbufptrptr);
- return;
- };
-
- /* We're dealing with a vnode object here: */
- UnpackCommonAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
-
-#if 0
- switch (vp->v_type) {
- case VDIR:
- UnpackDirAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- case VREG:
- /* case VCPLX: */ /* XXX PPD TBC */
- UnpackFileAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- case VFORK:
- UnpackForkAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- /* Without this the compiler complains about VNON,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD and VSTR
- not being handled...
- */
- default:
- /* XXX PPD - Panic? */
- break;
- };
-#endif
-
-};
-
-
-unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
- unsigned long blockSizeLimit,
- unsigned long baseMultiple) {
- /*
- Compute the optimal (largest) block size (no larger than allocationBlockSize) that is less than the
- specified limit but still an even multiple of the baseMultiple.
- */
- int baseBlockCount, blockCount;
- unsigned long trialBlockSize;
-
- if (allocationBlockSize % baseMultiple != 0) {
- /*
- Whoops: the allocation blocks aren't even multiples of the specified base:
- no amount of dividing them into even parts will be a multiple, either then!
- */
- return 512; /* Hope for the best */
- };
-
- /* Try the obvious winner first, to prevent 12K allocation blocks, for instance,
- from being handled as two 6K logical blocks instead of 3 4K logical blocks.
- Even though the former (the result of the loop below) is the larger allocation
- block size, the latter is more efficient: */
- if (allocationBlockSize % PAGE_SIZE == 0) return PAGE_SIZE;
-
- /* No clear winner exists: pick the largest even fraction <= MAXBSIZE: */
- baseBlockCount = allocationBlockSize / baseMultiple; /* Now guaranteed to be an even multiple */
-
- for (blockCount = baseBlockCount; blockCount > 0; --blockCount) {
- trialBlockSize = blockCount * baseMultiple;
- if (allocationBlockSize % trialBlockSize == 0) { /* An even multiple? */
- if ((trialBlockSize <= blockSizeLimit) &&
- (trialBlockSize % baseMultiple == 0)) {
- return trialBlockSize;
- };
- };
- };
-
- /* Note: we should never get here, since blockCount = 1 should always work,
- but this is nice and safe and makes the compiler happy, too ... */
- return 512;
-}
-
-
-/*
- * To make the HFS Plus filesystem follow UFS unlink semantics, a remove
- * of an active vnode is translated to a move/rename so the file appears
- * deleted. The destination folder for these move/renames is setup here
- * and a reference to it is place in hfsmp->hfs_private_metadata_dir.
- */
-u_long
-FindMetaDataDirectory(ExtendedVCB *vcb)
-{
- char namep[32];
- hfsCatalogInfo catInfo;
- HFSCatalogNodeID dirID;
- u_int32_t metadata_createdate;
- int retval;
-
- if (vcb->vcbSigWord != kHFSPlusSigWord)
- return (0);
-
- dirID = 0;
- metadata_createdate = 0;
- strncpy(namep, HFSPLUS_PRIVATE_DIR, sizeof(namep));
- INIT_CATALOGDATA(&catInfo.nodeData, kCatNameNoCopyName);
- catInfo.hint = kNoHint;
-
- /* lock catalog b-tree */
- retval = hfs_metafilelocking(VCBTOHFS(vcb), kHFSCatalogFileID, LK_SHARED, current_proc());
- if (retval) goto Err_Exit;
-
- if (hfs_getcatalog(vcb, kRootDirID, namep, -1, &catInfo) == 0) {
- dirID = catInfo.nodeData.cnd_nodeID;
- metadata_createdate = catInfo.nodeData.cnd_createDate;
- } else if (VCBTOHFS(vcb)->hfs_fs_ronly == 0) {
- if (CreateCatalogNode(vcb, kRootDirID, namep, kCatalogFolderNode, &dirID, &catInfo.hint, 0) == 0) {
- catInfo.hint = kNoHint;
- if (hfs_getcatalog(vcb, kRootDirID, namep, -1, &catInfo) == 0) {
-
- /* create date is later used for validation */
- catInfo.nodeData.cnd_createDate = vcb->vcbCrDate;
- metadata_createdate = catInfo.nodeData.cnd_createDate;
-
- /* directory with no permissions owned by root */
- catInfo.nodeData.cnd_mode = IFDIR;
- catInfo.nodeData.cnd_adminFlags = (SF_IMMUTABLE >> 16);
-
- /* hidden and off the desktop view */
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frLocation.v = SWAP_BE16 (22460);
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frLocation.h = SWAP_BE16 (22460);
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frFlags |= SWAP_BE16 (kIsInvisible + kNameLocked);
-
- (void) UpdateCatalogNode(vcb, kRootDirID, namep, catInfo.hint, &catInfo.nodeData);