-/*
-
-#
-#% getattrlist vp = = =
-#
- vnop_getattrlist {
- IN struct vnode *vp;
- IN struct attrlist *alist;
- INOUT struct uio *uio;
- IN vfs_context_t context;
- };
-
- */
-int
-cd9660_getattrlist(struct vnop_getattrlist_args *ap)
-{
- struct attrlist *alist = ap->a_alist;
- int fixedblocksize;
- int attrblocksize;
- int attrbufsize;
- void *attrbufptr;
- void *attrptr;
- void *varptr;
- int error = 0;
-
- if ((alist->bitmapcount != ATTR_BIT_MAP_COUNT) ||
- ((alist->commonattr & ~ATTR_CMN_VALIDMASK) != 0) ||
- ((alist->volattr & ~ATTR_VOL_VALIDMASK) != 0) ||
- ((alist->dirattr & ~ATTR_DIR_VALIDMASK) != 0) ||
- ((alist->fileattr & ~ATTR_FILE_VALIDMASK) != 0) ||
- ((alist->forkattr & ~ATTR_FORK_VALIDMASK) != 0)) {
- return EINVAL;
- };
-
- /*
- * Requesting volume information requires setting the ATTR_VOL_INFO bit and
- * volume info requests are mutually exclusive with all other info requests:
- */
- if ((alist->volattr != 0) &&
- (((alist->volattr & ATTR_VOL_INFO) == 0) ||
- (alist->dirattr != 0) ||
- (alist->fileattr != 0) ||
- (alist->forkattr != 0) )) {
- return EINVAL;
- };
-
- /*
- * Reject requests for unsupported options for now:
- */
- if (alist->volattr & ATTR_VOL_MOUNTPOINT) return EINVAL;
- if (alist->commonattr & (ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)) return EINVAL;
- if (alist->fileattr &
- (ATTR_FILE_FILETYPE |
- ATTR_FILE_FORKCOUNT |
- ATTR_FILE_FORKLIST |
- ATTR_FILE_DATAEXTENTS |
- ATTR_FILE_RSRCEXTENTS)) {
- return EINVAL;
- };
-
-
- fixedblocksize = attrcalcsize(alist);
- attrblocksize = fixedblocksize + (sizeof(uint32_t)); /* uint32_t for length word */
- if (alist->commonattr & ATTR_CMN_NAME) attrblocksize += NAME_MAX;
- if (alist->commonattr & ATTR_CMN_NAMEDATTRLIST) attrblocksize += 0; /* XXX PPD */
- if (alist->volattr & ATTR_VOL_MOUNTPOINT) attrblocksize += PATH_MAX;
- if (alist->volattr & ATTR_VOL_NAME) attrblocksize += NAME_MAX;
- if (alist->fileattr & ATTR_FILE_FORKLIST) attrblocksize += 0; /* XXX PPD */
-
- attrbufsize = MIN(uio_resid(ap->a_uio), attrblocksize);
- MALLOC(attrbufptr, void *, attrblocksize, M_TEMP, M_WAITOK);
- attrptr = attrbufptr;
- *((uint32_t *)attrptr) = 0; /* Set buffer length in case of errors */
- ++((uint32_t *)attrptr); /* Reserve space for length field */
- varptr = ((char *)attrptr) + fixedblocksize; /* Point to variable-length storage */
-
- packattrblk(alist, ap->a_vp, &attrptr, &varptr);
-
- /* Store length of fixed + var block */
- *((uint32_t *)attrbufptr) = ((char*)varptr - (char*)attrbufptr);
- /* Don't copy out more data than was generated */
- attrbufsize = MIN(attrbufsize, (char*)varptr - (char*)attrbufptr);
-
- error = uiomove((caddr_t)attrbufptr, attrbufsize, ap->a_uio);
-
- FREE(attrbufptr, M_TEMP);
-
- return error;
-}
-