-
-
-
-void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData)
-{
- ExtendedVCB *vcb;
- FCB *fcb;
- struct hfsnode *hp;
- Boolean isHFSPlus, isResource;
- HFSPlusExtentDescriptor *extents;
- off_t fileReadLimit;
-
- hp = VTOH(vp);
- vcb = HTOVCB(hp);
- fcb = HTOFCB(hp);
- isResource = (H_FORKTYPE(hp) == kRsrcFork);
- isHFSPlus = (vcb->vcbSigWord == kHFSPlusSigWord);
-
- /* date and time of last fork modification */
- if (hp->h_meta->h_mtime != 0)
- nodeData->cnd_contentModDate = to_hfs_time(hp->h_meta->h_mtime);
-
- if (isHFSPlus) {
- /* Make sure that there is no nodeType/mode mismatch */
- if ((nodeData->cnd_type == kCatalogFolderNode)
- && ((hp->h_meta->h_mode & IFMT) != IFDIR)) {
-
- DBG_ASSERT((hp->h_meta->h_mode & IFMT) == IFDIR);
- hp->h_meta->h_mode &= ~IFMT; /* Clear the bad bits */
- hp->h_meta->h_mode |= IFDIR; /* Set the proper one */
- };
- /* date and time of last modification (any kind) */
- if (hp->h_meta->h_ctime != 0)
- nodeData->cnd_attributeModDate = to_hfs_time(hp->h_meta->h_ctime);
- /* date and time of last access (MacOS X only) */
- if (hp->h_meta->h_atime != 0)
- nodeData->cnd_accessDate = to_hfs_time(hp->h_meta->h_atime);
- /* hfs_setattr can change the create date */
- if (hp->h_meta->h_crtime != 0)
- nodeData->cnd_createDate = to_hfs_time(hp->h_meta->h_crtime);
- if (! (hp->h_meta->h_metaflags & IN_UNSETACCESS)) {
- nodeData->cnd_adminFlags = hp->h_meta->h_pflags >> 16;
- nodeData->cnd_ownerFlags = hp->h_meta->h_pflags & 0x000000FF;
- nodeData->cnd_mode = hp->h_meta->h_mode;
- nodeData->cnd_ownerID = hp->h_meta->h_uid;
- nodeData->cnd_groupID = hp->h_meta->h_gid;
- }
- };
-
- /* the rest only applies to files */
- if (nodeData->cnd_type == kCatalogFileNode) {
- if (hp->h_meta->h_pflags & (SF_IMMUTABLE | UF_IMMUTABLE)) {
- /* The file is locked: set the locked bit in the catalog. */
- nodeData->cnd_flags |= kHFSFileLockedMask;
- } else {
- /* The file is unlocked: make sure the locked bit in the catalog is clear. */
- nodeData->cnd_flags &= ~kHFSFileLockedMask;
- };
- if (CIRCLEQ_EMPTY(&hp->h_invalidranges)) {
- fileReadLimit = fcb->fcbEOF;
- } else {
- fileReadLimit = CIRCLEQ_FIRST(&hp->h_invalidranges)->rl_start;
- };
- if (isResource) {
- extents = nodeData->cnd_rsrcfork.extents;
- nodeData->cnd_rsrcfork.logicalSize = fileReadLimit;
- nodeData->cnd_rsrcfork.totalBlocks = fcb->fcbPLen / vcb->blockSize;
- } else {
- extents = nodeData->cnd_datafork.extents;
- nodeData->cnd_datafork.logicalSize = fileReadLimit;
- nodeData->cnd_datafork.totalBlocks = fcb->fcbPLen / vcb->blockSize;
- };
-
- bcopy ( fcb->fcbExtents, extents, sizeof(HFSPlusExtentRecord));
-
- if ((vp->v_type == VBLK) || (vp->v_type == VCHR))
- nodeData->cnd_rawDevice = hp->h_meta->h_rdev;
- else if (hp->h_meta->h_metaflags & IN_DATANODE)
- nodeData->cnd_linkCount = hp->h_meta->h_nlink;
-
- if (vp->v_type == VLNK) {
- ((struct FInfo *)(&nodeData->cnd_finderInfo))->fdType = SWAP_BE32 (kSymLinkFileType);
- ((struct FInfo *)(&nodeData->cnd_finderInfo))->fdCreator = SWAP_BE32 (kSymLinkCreator);
-
- /* Set this up as an alias */
- #if SUPPORTS_MAC_ALIASES
- ((struct FInfo *)(&nodeData->cnd_finderInfo))->fdFlags |= SWAP_BE16 (kIsAlias);
- #endif
- }
- }
- }
-
-
-/*********************************************************************
-
- Sets the name in the filemeta structure
-
- XXX Does not preflight if changing from one size to another
- XXX Currently not protected from context switching
-
-*********************************************************************/
-
-void hfs_set_metaname(char *name, struct hfsfilemeta *fm, struct hfsmount *hfsmp)
-{
-int namelen = strlen(name);
-char *tname, *fname;
-
-#if HFS_DIAGNOSTIC
- DBG_ASSERT(name != NULL);
- DBG_ASSERT(fm != NULL);
- if (fm->h_namePtr) {
- DBG_ASSERT(fm->h_namelen == strlen(fm->h_namePtr));
- if (strlen(fm->h_namePtr) > MAXHFSVNODELEN)
- DBG_ASSERT(fm->h_metaflags & IN_LONGNAME);
- };
- if (fm->h_metaflags & IN_LONGNAME) {
- DBG_ASSERT(fm->h_namePtr != (char *)fm->h_fileName);
- DBG_ASSERT(fm->h_namePtr != NULL);
- };
-#endif //HFS_DIAGNOSTIC
-
- /*
- * Details that have to be dealt with:
- * 1. No name is allocated. fm->h_namePtr should be NULL
- * 2. A name is being changed and:
- * a. it was in static space and now cannot fit
- * b. It was malloc'd and now will fit in the static
- * c. It did and will fit in the static
- * This could be a little smarter:
- * - Dont re'malloc if the new name is smaller (but then wasting memory)
- * - If its a longname but the same size, we still free and malloc
- * -
- */
-
-
- /* Allocate the new memory */
- if (namelen > MAXHFSVNODELEN) {
- /*
- * Notice the we ALWAYS allocate, even if the new is less then the old,
- * or even if they are the SAME
- */
- MALLOC(tname, char *, namelen+1, M_TEMP, M_WAITOK);
- }
- else
- tname = fm->h_fileName;
-
- simple_lock(&hfsmp->hfs_renamelock);
-
- /* Check to see if there is something to free, if yes, remember it */
- if (fm->h_metaflags & IN_LONGNAME)
- fname = fm->h_namePtr;
- else
- fname = NULL;
-
- /* Set the flag */
- if (namelen > MAXHFSVNODELEN) {
- fm->h_metaflags |= IN_LONGNAME;
- }
- else {
- fm->h_metaflags &= ~IN_LONGNAME;
- };
-
- /* Now copy it over */
- bcopy(name, tname, namelen+1);
-
- fm->h_namePtr = tname;
- fm->h_namelen = namelen;
-
- simple_unlock(&hfsmp->hfs_renamelock);
-
- /* Lastly, free the old, if set */
- if (fname != NULL)
- FREE(fname, M_TEMP);
-
-}
-
-void hfs_name_CatToMeta(CatalogNodeData *nodeData, struct hfsfilemeta *fm)
-{
-char *fname;
-
-#if HFS_DIAGNOSTIC
- DBG_ASSERT(nodeData != NULL);
- DBG_ASSERT(fm != NULL);
- if (fm->h_namePtr) {
- DBG_ASSERT(fm->h_namelen == strlen(fm->h_namePtr));
- if (strlen(fm->h_namePtr) > MAXHFSVNODELEN)
- DBG_ASSERT(fm->h_metaflags & IN_LONGNAME);
- };
- if (fm->h_metaflags & IN_LONGNAME) {
- DBG_ASSERT(fm->h_namePtr != (char *)fm->h_fileName);
- DBG_ASSERT(fm->h_namePtr != NULL);
- };
-
- DBG_ASSERT(nodeData->cnm_nameptr != NULL);
-
- if (nodeData->cnm_length) {
- DBG_ASSERT(strlen(nodeData->cnm_nameptr) == nodeData->cnm_length);
- }
-
- if (nodeData->cnm_length > MAXHFSVNODELEN)
- { DBG_ASSERT(nodeData->cnm_nameptr != nodeData->cnm_namespace); }
- else if (nodeData->cnm_nameptr)
- { DBG_ASSERT(nodeData->cnm_nameptr == nodeData->cnm_namespace); }
-
-#endif //HFS_DIAGNOSTIC
-
-
- /* Check to see if there is something to free, if yes, remember it */
- if (fm->h_metaflags & IN_LONGNAME)
- fname = fm->h_namePtr;
- else
- fname = NULL;
-
- /* Set the flag */
- if (nodeData->cnm_length > MAXHFSVNODELEN) {
- fm->h_metaflags |= IN_LONGNAME;
- } else {
- fm->h_metaflags &= ~IN_LONGNAME;
- };
-
- /* Copy over the name */
- if (nodeData->cnm_nameptr == nodeData->cnm_namespace) {
- bcopy(nodeData->cnm_namespace, fm->h_fileName, nodeData->cnm_length+1);
- fm->h_namePtr = fm->h_fileName;
- }
- else {
- fm->h_namePtr = nodeData->cnm_nameptr;
- }
-
- fm->h_namelen = nodeData->cnm_length;
-
- nodeData->cnm_flags |= kCatNameIsConsumed;
- nodeData->cnm_flags &= ~kCatNameIsAllocated;
- nodeData->cnm_length = 0;
- nodeData->cnm_nameptr = (char *)0;
- nodeData->cnm_namespace[0] = 0;
-
- /* Lastly, free the old, if set */
- if (fname != NULL)
- FREE(fname, M_TEMP);
-}
-
-
-
-unsigned long DerivePermissionSummary(uid_t obj_uid, gid_t obj_gid, mode_t obj_mode, struct mount *mp, struct ucred *cred, struct proc *p) {
- register gid_t *gp;
- unsigned long permissions;
- int i;
-
- /* User id 0 (root) always gets access. */
- if (cred->cr_uid == 0) {
- permissions = R_OK | W_OK | X_OK;
- goto Exit;
- };
-
- /* Otherwise, check the owner. */
- if (hfs_catalogentry_owner_rights(obj_uid, mp, cred, p, false) == 0) {
- permissions = ((unsigned long)obj_mode & S_IRWXU) >> 6;
- goto Exit;
- }
-
- /* Otherwise, check the groups. */
- if (! (mp->mnt_flag & MNT_UNKNOWNPERMISSIONS)) {
- for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) {
- if (obj_gid == *gp) {
- permissions = ((unsigned long)obj_mode & S_IRWXG) >> 3;
- goto Exit;
- }
- };
- };
-
- /* Otherwise, settle for 'others' access. */
- permissions = (unsigned long)obj_mode & S_IRWXO;
-
-Exit:
- return permissions;
-}
-
-
-
-int AttributeBlockSize(struct attrlist *attrlist) {
- int size;
- attrgroup_t a;
-
-#if ((ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_FSID | ATTR_CMN_OBJTYPE | \
- ATTR_CMN_OBJTAG | ATTR_CMN_OBJID | ATTR_CMN_OBJPERMANENTID | ATTR_CMN_PAROBJID | \
- ATTR_CMN_SCRIPT | ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | \
- ATTR_CMN_ACCTIME | ATTR_CMN_BKUPTIME | ATTR_CMN_FNDRINFO | ATTR_CMN_OWNERID | \
- ATTR_CMN_GRPID | ATTR_CMN_ACCESSMASK | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST| \
- ATTR_CMN_FLAGS | ATTR_CMN_USERACCESS) != ATTR_CMN_VALIDMASK)
-#error AttributeBlockSize: Missing bits in common mask computation!
-#endif
- DBG_ASSERT((attrlist->commonattr & ~ATTR_CMN_VALIDMASK) == 0);
-
-#if ((ATTR_VOL_FSTYPE | ATTR_VOL_SIGNATURE | ATTR_VOL_SIZE | ATTR_VOL_SPACEFREE | \
- ATTR_VOL_SPACEAVAIL | ATTR_VOL_MINALLOCATION | ATTR_VOL_ALLOCATIONCLUMP | ATTR_VOL_IOBLOCKSIZE | \
- ATTR_VOL_OBJCOUNT | ATTR_VOL_FILECOUNT | ATTR_VOL_DIRCOUNT | ATTR_VOL_MAXOBJCOUNT | \
- ATTR_VOL_MOUNTPOINT | ATTR_VOL_NAME | ATTR_VOL_MOUNTFLAGS | ATTR_VOL_INFO | \
- ATTR_VOL_MOUNTEDDEVICE| ATTR_VOL_ENCODINGSUSED | ATTR_VOL_CAPABILITIES | ATTR_VOL_ATTRIBUTES) != ATTR_VOL_VALIDMASK)
-#error AttributeBlockSize: Missing bits in volume mask computation!
-#endif
- DBG_ASSERT((attrlist->volattr & ~ATTR_VOL_VALIDMASK) == 0);
-
-#if ((ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT | ATTR_DIR_MOUNTSTATUS) != ATTR_DIR_VALIDMASK)
-#error AttributeBlockSize: Missing bits in directory mask computation!
-#endif
- DBG_ASSERT((attrlist->dirattr & ~ATTR_DIR_VALIDMASK) == 0);
-#if ((ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | ATTR_FILE_IOBLOCKSIZE | \
- ATTR_FILE_CLUMPSIZE | ATTR_FILE_DEVTYPE | ATTR_FILE_FILETYPE | ATTR_FILE_FORKCOUNT | \
- ATTR_FILE_FORKLIST | ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \
- ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS) != ATTR_FILE_VALIDMASK)
-#error AttributeBlockSize: Missing bits in file mask computation!
-#endif
- DBG_ASSERT((attrlist->fileattr & ~ATTR_FILE_VALIDMASK) == 0);
-
-#if ((ATTR_FORK_TOTALSIZE | ATTR_FORK_ALLOCSIZE) != ATTR_FORK_VALIDMASK)
-#error AttributeBlockSize: Missing bits in fork mask computation!
-#endif
- DBG_ASSERT((attrlist->forkattr & ~ATTR_FORK_VALIDMASK) == 0);
-
- size = 0;
-
- if ((a = attrlist->commonattr) != 0) {
- if (a & ATTR_CMN_NAME) size += sizeof(struct attrreference);
- if (a & ATTR_CMN_DEVID) size += sizeof(dev_t);
- if (a & ATTR_CMN_FSID) size += sizeof(fsid_t);
- if (a & ATTR_CMN_OBJTYPE) size += sizeof(fsobj_type_t);
- if (a & ATTR_CMN_OBJTAG) size += sizeof(fsobj_tag_t);
- if (a & ATTR_CMN_OBJID) size += sizeof(fsobj_id_t);
- if (a & ATTR_CMN_OBJPERMANENTID) size += sizeof(fsobj_id_t);
- if (a & ATTR_CMN_PAROBJID) size += sizeof(fsobj_id_t);
- if (a & ATTR_CMN_SCRIPT) size += sizeof(text_encoding_t);
- if (a & ATTR_CMN_CRTIME) size += sizeof(struct timespec);
- if (a & ATTR_CMN_MODTIME) size += sizeof(struct timespec);
- if (a & ATTR_CMN_CHGTIME) size += sizeof(struct timespec);
- if (a & ATTR_CMN_ACCTIME) size += sizeof(struct timespec);
- if (a & ATTR_CMN_BKUPTIME) size += sizeof(struct timespec);
- if (a & ATTR_CMN_FNDRINFO) size += 32 * sizeof(UInt8);
- if (a & ATTR_CMN_OWNERID) size += sizeof(uid_t);
- if (a & ATTR_CMN_GRPID) size += sizeof(gid_t);
- if (a & ATTR_CMN_ACCESSMASK) size += sizeof(u_long);
- if (a & ATTR_CMN_NAMEDATTRCOUNT) size += sizeof(u_long);
- if (a & ATTR_CMN_NAMEDATTRLIST) size += sizeof(struct attrreference);
- if (a & ATTR_CMN_FLAGS) size += sizeof(u_long);
- if (a & ATTR_CMN_USERACCESS) size += sizeof(u_long);
- };
- if ((a = attrlist->volattr) != 0) {
- if (a & ATTR_VOL_FSTYPE) size += sizeof(u_long);
- if (a & ATTR_VOL_SIGNATURE) size += sizeof(u_long);
- if (a & ATTR_VOL_SIZE) size += sizeof(off_t);
- if (a & ATTR_VOL_SPACEFREE) size += sizeof(off_t);
- if (a & ATTR_VOL_SPACEAVAIL) size += sizeof(off_t);
- if (a & ATTR_VOL_MINALLOCATION) size += sizeof(off_t);
- if (a & ATTR_VOL_ALLOCATIONCLUMP) size += sizeof(off_t);
- if (a & ATTR_VOL_IOBLOCKSIZE) size += sizeof(u_long);
- if (a & ATTR_VOL_OBJCOUNT) size += sizeof(u_long);
- if (a & ATTR_VOL_FILECOUNT) size += sizeof(u_long);
- if (a & ATTR_VOL_DIRCOUNT) size += sizeof(u_long);
- if (a & ATTR_VOL_MAXOBJCOUNT) size += sizeof(u_long);
- if (a & ATTR_VOL_MOUNTPOINT) size += sizeof(struct attrreference);
- if (a & ATTR_VOL_NAME) size += sizeof(struct attrreference);
- if (a & ATTR_VOL_MOUNTFLAGS) size += sizeof(u_long);
- if (a & ATTR_VOL_MOUNTEDDEVICE) size += sizeof(struct attrreference);
- if (a & ATTR_VOL_ENCODINGSUSED) size += sizeof(unsigned long long);
- if (a & ATTR_VOL_CAPABILITIES) size += sizeof(vol_capabilities_attr_t);
- if (a & ATTR_VOL_ATTRIBUTES) size += sizeof(vol_attributes_attr_t);
- };
- if ((a = attrlist->dirattr) != 0) {
- if (a & ATTR_DIR_LINKCOUNT) size += sizeof(u_long);
- if (a & ATTR_DIR_ENTRYCOUNT) size += sizeof(u_long);
- if (a & ATTR_DIR_MOUNTSTATUS) size += sizeof(u_long);
- };
- if ((a = attrlist->fileattr) != 0) {
- if (a & ATTR_FILE_LINKCOUNT) size += sizeof(u_long);
- if (a & ATTR_FILE_TOTALSIZE) size += sizeof(off_t);
- if (a & ATTR_FILE_ALLOCSIZE) size += sizeof(off_t);
- if (a & ATTR_FILE_IOBLOCKSIZE) size += sizeof(size_t);
- if (a & ATTR_FILE_CLUMPSIZE) size += sizeof(off_t);
- if (a & ATTR_FILE_DEVTYPE) size += sizeof(u_long);
- if (a & ATTR_FILE_FILETYPE) size += sizeof(u_long);
- if (a & ATTR_FILE_FORKCOUNT) size += sizeof(u_long);
- if (a & ATTR_FILE_FORKLIST) size += sizeof(struct attrreference);
- if (a & ATTR_FILE_DATALENGTH) size += sizeof(off_t);
- if (a & ATTR_FILE_DATAALLOCSIZE) size += sizeof(off_t);
- if (a & ATTR_FILE_DATAEXTENTS) size += sizeof(extentrecord);
- if (a & ATTR_FILE_RSRCLENGTH) size += sizeof(off_t);
- if (a & ATTR_FILE_RSRCALLOCSIZE) size += sizeof(off_t);
- if (a & ATTR_FILE_RSRCEXTENTS) size += sizeof(extentrecord);
- };
- if ((a = attrlist->forkattr) != 0) {
- if (a & ATTR_FORK_TOTALSIZE) size += sizeof(off_t);
- if (a & ATTR_FORK_ALLOCSIZE) size += sizeof(off_t);
- };
-
- return size;
-}
-
-
-
-char* FindMountpointName(struct mount *mp) {
- size_t namelength = strlen(mp->mnt_stat.f_mntonname);
- int foundchars = 0;
- char *c;
-
- if (namelength == 0) return NULL;
-
- /* Look backwards through the name string, looking for the first slash
- encountered (which must precede the last part of the pathname)
- */
- for (c = mp->mnt_stat.f_mntonname + namelength - 1; namelength > 0; --c, --namelength) {
- if (*c != '/') {
- foundchars = 1;
- } else if (foundchars) {
- return (c + 1);
- };
- };
-
- return mp->mnt_stat.f_mntonname;
-}
-
-
-
-void PackObjectName(struct vnode *vp,
- char *name,
- size_t namelen,
- void **attrbufptrptr,
- void **varbufptrptr) {
- char *mpname;
- size_t mpnamelen;
- u_long attrlength;
-
- /* The name of an object may be incorrect for the root of a mounted filesystem
- because it may be mounted on a different directory name than the name of the
- volume (such as "blah-1". For the root directory, it's best to return the
- last element of the location where the volume's mounted:
- */
- if ((vp->v_flag & VROOT) && (mpname = FindMountpointName(vp->v_mount))) {
- mpnamelen = strlen(mpname);
-
- /* Trim off any trailing slashes: */
- while ((mpnamelen > 0) && (mpname[mpnamelen-1] == '/')) {
- --mpnamelen;
- };
-
- /* 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;