static void cd9660_rrip_defname(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana) { isofntrans(isodir->name,isonum_711(isodir->name_len), ana->outbuf,ana->outlen, 1,isonum_711(isodir->flags)&4, ana->imp->joliet_level, ana->imp->im_flags, ana->imp->im_d2l); switch (*ana->outbuf) { default: break; case 1: *ana->outlen = 2; /* FALL THROUGH */ case 0: /* outlen is 1 already */ strcpy(ana->outbuf,".."); break; } }
static void cd9660_rrip_defname(void *v, ISO_RRIP_ANALYZE *ana) { struct iso_directory_record *isodir = v; isofntrans(isodir->name, isonum_711(isodir->name_len), ana->outbuf, ana->outlen, 1, 0, isonum_711(isodir->flags) & 4, ana->imp->im_joliet_level); switch (ana->outbuf[0]) { default: break; case 0: ana->outbuf[0] = '.'; *ana->outlen = 1; break; case 1: strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen); *ana->outlen = 2; break; } }
/* * Vnode op for readdir */ int cd9660_readdir(void *v) { struct vop_readdir_args /* { struct vnode *a_vp; struct uio *a_uio; kauth_cred_t a_cred; int *a_eofflag; off_t **a_cookies; int *a_ncookies; } */ *ap = v; struct uio *uio = ap->a_uio; struct isoreaddir *idp; struct vnode *vdp = ap->a_vp; struct iso_node *dp; struct iso_mnt *imp; struct buf *bp = NULL; struct iso_directory_record *ep; int entryoffsetinblock; doff_t endsearch; u_long bmask; int error = 0; int reclen; u_short namelen; off_t *cookies = NULL; int ncookies = 0; if (vdp->v_type != VDIR) return (ENOTDIR); dp = VTOI(vdp); imp = dp->i_mnt; bmask = imp->im_bmask; idp = (struct isoreaddir *)malloc(sizeof(*idp), M_TEMP, M_WAITOK); idp->saveent.d_namlen = idp->assocent.d_namlen = 0; /* * XXX * Is it worth trying to figure out the type? */ idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = DT_UNKNOWN; idp->uio = uio; if (ap->a_ncookies == NULL) idp->cookies = NULL; else { ncookies = uio->uio_resid / _DIRENT_MINSIZE((struct dirent *)0); cookies = malloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); idp->cookies = cookies; idp->ncookies = ncookies; } idp->eofflag = 1; idp->curroff = uio->uio_offset; if ((entryoffsetinblock = idp->curroff & bmask) && (error = cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp))) { free(idp, M_TEMP); return (error); } endsearch = dp->i_size; while (idp->curroff < endsearch) { /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ if ((idp->curroff & bmask) == 0) { if (bp != NULL) brelse(bp, 0); error = cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp); if (error) break; entryoffsetinblock = 0; } /* * Get pointer to next entry. */ KASSERT(bp != NULL); ep = (struct iso_directory_record *) ((char *)bp->b_data + entryoffsetinblock); reclen = isonum_711(ep->length); if (reclen == 0) { /* skip to next block, if any */ idp->curroff = (idp->curroff & ~bmask) + imp->logical_block_size; continue; } if (reclen < ISO_DIRECTORY_RECORD_SIZE) { error = EINVAL; /* illegal entry, stop */ break; } if (entryoffsetinblock + reclen > imp->logical_block_size) { error = EINVAL; /* illegal directory, so stop looking */ break; } idp->current.d_namlen = isonum_711(ep->name_len); if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { error = EINVAL; /* illegal entry, stop */ break; } if (isonum_711(ep->flags)&2) idp->current.d_fileno = isodirino(ep, imp); else idp->current.d_fileno = dbtob(bp->b_blkno) + entryoffsetinblock; idp->curroff += reclen; switch (imp->iso_ftype) { case ISO_FTYPE_RRIP: cd9660_rrip_getname(ep, idp->current.d_name, &namelen, &idp->current.d_fileno, imp); idp->current.d_namlen = (u_char)namelen; if (idp->current.d_namlen) error = iso_uiodir(idp, &idp->current, idp->curroff); break; default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ isofntrans(ep->name, idp->current.d_namlen, idp->current.d_name, &namelen, imp->iso_ftype == ISO_FTYPE_9660, (imp->im_flags & ISOFSMNT_NOCASETRANS) == 0, isonum_711(ep->flags)&4, imp->im_joliet_level); switch (idp->current.d_name[0]) { case 0: idp->current.d_name[0] = '.'; idp->current.d_namlen = 1; error = iso_uiodir(idp, &idp->current, idp->curroff); break; case 1: strlcpy(idp->current.d_name, "..", sizeof(idp->current.d_name)); idp->current.d_namlen = 2; error = iso_uiodir(idp, &idp->current, idp->curroff); break; default: idp->current.d_namlen = (u_char)namelen; if (imp->iso_ftype == ISO_FTYPE_DEFAULT) error = iso_shipdir(idp); else error = iso_uiodir(idp, &idp->current, idp->curroff); break; } } if (error) break; entryoffsetinblock += reclen; } if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { idp->current.d_namlen = 0; error = iso_shipdir(idp); } if (error < 0) error = 0; if (ap->a_ncookies != NULL) { if (error) free(cookies, M_TEMP); else { /* * Work out the number of cookies actually used. */ *ap->a_ncookies = ncookies - idp->ncookies; *ap->a_cookies = cookies; } } if (bp) brelse(bp, 0); uio->uio_offset = idp->uio_off; *ap->a_eofflag = idp->eofflag; free(idp, M_TEMP); return (error); }