Repocopied from src/sys/isofs/cd9660 to src/sys/fs/cd9660.
This commit is contained in:
parent
38cc2a5caa
commit
55fd006cc8
@ -1,43 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
2) should understand Rock Ridge
|
||||
|
||||
Yes, we have follows function.
|
||||
|
||||
o Symbolic Link
|
||||
o Real Name(long name)
|
||||
o File Attribute
|
||||
o Time stamp
|
||||
o uid, gid
|
||||
o Devices
|
||||
o Relocated directories
|
||||
|
||||
Except follows:
|
||||
|
||||
o POSIX device number mapping
|
||||
|
||||
There is some preliminary stuff in there that (ab-)uses the mknod
|
||||
system call, but this needs a writable filesystem
|
||||
|
||||
5) should have name translation enabled by mount flag
|
||||
|
||||
Yes. we can disable the Rock Ridge Extension by follows option;
|
||||
|
||||
"mount -t isofs -o -norrip /dev/cd0d /cdrom"
|
||||
|
||||
6) should run as a user process, and not take up kernel space (cdroms
|
||||
are slow)
|
||||
|
||||
Not yet.
|
||||
|
||||
7) ECMA support.
|
||||
|
||||
Not yet. we need not only a technical spec but also ECMA format
|
||||
cd-rom itself!
|
||||
|
||||
8) Character set change by SVD ( multi SVD support )
|
||||
|
||||
Not yet. We should also hack the other part of system as 8 bit
|
||||
clean. As far as I know, if you export the cdrom by NFS, the client
|
||||
can access the 8 bit clean (ie. Solaris Japanese with EUC code )
|
||||
|
@ -1,16 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
1. Investiate making ISOFS another UFS shared filesystem (ala FFS/MFS/LFS).
|
||||
Since it was modelled after the inode code, we might be able to merge
|
||||
them back. It looks like a separate (but very similar) lookup routine
|
||||
will be needed due to the associated file stuff.
|
||||
|
||||
2. It would be nice to be able to use the vfs_cluster code.
|
||||
Unfortunately, if the logical block size is smaller than the page size,
|
||||
it won't work. Also, if throughtput is relatively constant for any
|
||||
block size (as it is for the HP drive--150kbs) then clustering may not
|
||||
buy much (or may even hurt when vfs_cluster comes up with a large sync
|
||||
cluster).
|
||||
|
||||
3. Seems like there should be a "notrans" or some such mount option to show
|
||||
filenames as they really are without lower-casing. Does this make sense?
|
@ -1,104 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_bmap.c 8.3 (Berkeley) 1/23/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
|
||||
/*
|
||||
* Bmap converts a the logical block number of a file to its physical block
|
||||
* number on the disk. The conversion is done by using the logical block
|
||||
* number to index into the data block (extent) for the file.
|
||||
*/
|
||||
int
|
||||
cd9660_bmap(ap)
|
||||
struct vop_bmap_args /* {
|
||||
struct vnode *a_vp;
|
||||
daddr_t a_bn;
|
||||
struct bufobj **a_bop;
|
||||
daddr_t *a_bnp;
|
||||
int *a_runp;
|
||||
int *a_runb;
|
||||
} */ *ap;
|
||||
{
|
||||
struct iso_node *ip = VTOI(ap->a_vp);
|
||||
daddr_t lblkno = ap->a_bn;
|
||||
int bshift;
|
||||
|
||||
/*
|
||||
* Check for underlying vnode requests and ensure that logical
|
||||
* to physical mapping is requested.
|
||||
*/
|
||||
if (ap->a_bop != NULL)
|
||||
*ap->a_bop = &ip->i_mnt->im_devvp->v_bufobj;
|
||||
if (ap->a_bnp == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Compute the requested block number
|
||||
*/
|
||||
bshift = ip->i_mnt->im_bshift;
|
||||
*ap->a_bnp = (ip->iso_start + lblkno) << (bshift - DEV_BSHIFT);
|
||||
|
||||
/*
|
||||
* Determine maximum number of readahead blocks following the
|
||||
* requested block.
|
||||
*/
|
||||
if (ap->a_runp) {
|
||||
int nblk;
|
||||
|
||||
nblk = (ip->i_size >> bshift) - (lblkno + 1);
|
||||
if (nblk <= 0)
|
||||
*ap->a_runp = 0;
|
||||
else if (nblk >= (MAXBSIZE >> bshift))
|
||||
*ap->a_runp = (MAXBSIZE >> bshift) - 1;
|
||||
else
|
||||
*ap->a_runp = nblk;
|
||||
}
|
||||
|
||||
if (ap->a_runb) {
|
||||
*ap->a_runb = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Ryuichiro Imura
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
VFS_DECLARE_ICONV(cd9660);
|
@ -1,430 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
|
||||
* @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
|
||||
/*
|
||||
* Convert a component of a pathname into a pointer to a locked inode.
|
||||
* This is a very central and rather complicated routine.
|
||||
* If the filesystem is not maintained in a strict tree hierarchy,
|
||||
* this can result in a deadlock situation (see comments in code below).
|
||||
*
|
||||
* The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
|
||||
* whether the name is to be looked up, created, renamed, or deleted.
|
||||
* When CREATE, RENAME, or DELETE is specified, information usable in
|
||||
* creating, renaming, or deleting a directory entry may be calculated.
|
||||
* If flag has LOCKPARENT or'ed into it and the target of the pathname
|
||||
* exists, lookup returns both the target and its parent directory locked.
|
||||
* When creating or renaming and LOCKPARENT is specified, the target may
|
||||
* not be ".". When deleting and LOCKPARENT is specified, the target may
|
||||
* be "."., but the caller must check to ensure it does an vrele and iput
|
||||
* instead of two iputs.
|
||||
*
|
||||
* Overall outline of ufs_lookup:
|
||||
*
|
||||
* search for name in directory, to found or notfound
|
||||
* notfound:
|
||||
* if creating, return locked directory, leaving info on available slots
|
||||
* else return error
|
||||
* found:
|
||||
* if at end of path and deleting, return information to allow delete
|
||||
* if at end of path and rewriting (RENAME and LOCKPARENT), lock target
|
||||
* inode and return info to allow rewrite
|
||||
* if not at end, add name to cache; if at end and neither creating
|
||||
* nor deleting, add name to cache
|
||||
*
|
||||
* NOTE: (LOOKUP | LOCKPARENT) currently returns the parent inode unlocked.
|
||||
*/
|
||||
int
|
||||
cd9660_lookup(ap)
|
||||
struct vop_cachedlookup_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vdp; /* vnode for directory being searched */
|
||||
struct iso_node *dp; /* inode for directory being searched */
|
||||
struct iso_mnt *imp; /* filesystem that directory is in */
|
||||
struct buf *bp; /* a buffer of directory entries */
|
||||
struct iso_directory_record *ep = 0;/* the current directory entry */
|
||||
int entryoffsetinblock; /* offset of ep in bp's buffer */
|
||||
int saveoffset = 0; /* offset of last directory entry in dir */
|
||||
int numdirpasses; /* strategy for directory search */
|
||||
doff_t endsearch; /* offset to end directory search */
|
||||
struct vnode *pdp; /* saved dp during symlink work */
|
||||
struct vnode *tdp; /* returned by cd9660_vget_internal */
|
||||
u_long bmask; /* block offset mask */
|
||||
int error;
|
||||
ino_t ino = 0, saved_ino;
|
||||
int reclen;
|
||||
u_short namelen;
|
||||
int isoflags;
|
||||
char altname[NAME_MAX];
|
||||
int res;
|
||||
int assoc, len;
|
||||
char *name;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
int flags = cnp->cn_flags;
|
||||
int nameiop = cnp->cn_nameiop;
|
||||
struct thread *td = cnp->cn_thread;
|
||||
|
||||
bp = NULL;
|
||||
*vpp = NULL;
|
||||
vdp = ap->a_dvp;
|
||||
dp = VTOI(vdp);
|
||||
imp = dp->i_mnt;
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
*/
|
||||
|
||||
len = cnp->cn_namelen;
|
||||
name = cnp->cn_nameptr;
|
||||
/*
|
||||
* A leading `=' means, we are looking for an associated file
|
||||
*/
|
||||
if ((assoc = (imp->iso_ftype != ISO_FTYPE_RRIP && *name == ASSOCCHAR)))
|
||||
{
|
||||
len--;
|
||||
name++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is cached information on a previous search of
|
||||
* this directory, pick up where we last left off.
|
||||
* We cache only lookups as these are the most common
|
||||
* and have the greatest payoff. Caching CREATE has little
|
||||
* benefit as it usually must search the entire directory
|
||||
* to determine that the entry does not exist. Caching the
|
||||
* location of the last DELETE or RENAME has not reduced
|
||||
* profiling time and hence has been removed in the interest
|
||||
* of simplicity.
|
||||
*/
|
||||
bmask = imp->im_bmask;
|
||||
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
|
||||
dp->i_diroff > dp->i_size) {
|
||||
entryoffsetinblock = 0;
|
||||
dp->i_offset = 0;
|
||||
numdirpasses = 1;
|
||||
} else {
|
||||
dp->i_offset = dp->i_diroff;
|
||||
if ((entryoffsetinblock = dp->i_offset & bmask) &&
|
||||
(error = cd9660_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)))
|
||||
return (error);
|
||||
numdirpasses = 2;
|
||||
nchstats.ncs_2passes++;
|
||||
}
|
||||
endsearch = dp->i_size;
|
||||
|
||||
searchloop:
|
||||
while (dp->i_offset < endsearch) {
|
||||
/*
|
||||
* If offset is on a block boundary,
|
||||
* read the next directory block.
|
||||
* Release previous if it exists.
|
||||
*/
|
||||
if ((dp->i_offset & bmask) == 0) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if ((error =
|
||||
cd9660_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
|
||||
return (error);
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
/*
|
||||
* Get pointer to next entry.
|
||||
*/
|
||||
ep = (struct iso_directory_record *)
|
||||
((char *)bp->b_data + entryoffsetinblock);
|
||||
|
||||
reclen = isonum_711(ep->length);
|
||||
if (reclen == 0) {
|
||||
/* skip to next block, if any */
|
||||
dp->i_offset =
|
||||
(dp->i_offset & ~bmask) + imp->logical_block_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
if (entryoffsetinblock + reclen > imp->logical_block_size)
|
||||
/* entries are not allowed to cross boundaries */
|
||||
break;
|
||||
|
||||
namelen = isonum_711(ep->name_len);
|
||||
isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA?
|
||||
&ep->date[6]: ep->flags);
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check for a name match.
|
||||
*/
|
||||
switch (imp->iso_ftype) {
|
||||
default:
|
||||
if (!(isoflags & 4) == !assoc) {
|
||||
if ((len == 1
|
||||
&& *name == '.')
|
||||
|| (flags & ISDOTDOT)) {
|
||||
if (namelen == 1
|
||||
&& ep->name[0] == ((flags & ISDOTDOT) ? 1 : 0)) {
|
||||
/*
|
||||
* Save directory entry's inode number and
|
||||
* release directory buffer.
|
||||
*/
|
||||
dp->i_ino = isodirino(ep, imp);
|
||||
goto found;
|
||||
}
|
||||
if (namelen != 1
|
||||
|| ep->name[0] != 0)
|
||||
goto notfound;
|
||||
} else if (!(res = isofncmp(name, len,
|
||||
ep->name, namelen,
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l,
|
||||
imp->im_l2d))) {
|
||||
if (isoflags & 2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
ino = dbtob(bp->b_blkno)
|
||||
+ entryoffsetinblock;
|
||||
saveoffset = dp->i_offset;
|
||||
} else if (ino)
|
||||
goto foundino;
|
||||
#ifdef NOSORTBUG /* On some CDs directory entries are not sorted correctly */
|
||||
else if (res < 0)
|
||||
goto notfound;
|
||||
else if (res > 0 && numdirpasses == 2)
|
||||
numdirpasses++;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case ISO_FTYPE_RRIP:
|
||||
if (isonum_711(ep->flags)&2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
ino = dbtob(bp->b_blkno) + entryoffsetinblock;
|
||||
dp->i_ino = ino;
|
||||
cd9660_rrip_getname(ep,altname,&namelen,&dp->i_ino,imp);
|
||||
if (namelen == cnp->cn_namelen
|
||||
&& !bcmp(name,altname,namelen))
|
||||
goto found;
|
||||
ino = 0;
|
||||
break;
|
||||
}
|
||||
dp->i_offset += reclen;
|
||||
entryoffsetinblock += reclen;
|
||||
}
|
||||
if (ino) {
|
||||
foundino:
|
||||
dp->i_ino = ino;
|
||||
if (saveoffset != dp->i_offset) {
|
||||
if (lblkno(imp, dp->i_offset) !=
|
||||
lblkno(imp, saveoffset)) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if ((error = cd9660_blkatoff(vdp,
|
||||
(off_t)saveoffset, NULL, &bp)) != 0)
|
||||
return (error);
|
||||
}
|
||||
entryoffsetinblock = saveoffset & bmask;
|
||||
ep = (struct iso_directory_record *)
|
||||
((char *)bp->b_data + entryoffsetinblock);
|
||||
dp->i_offset = saveoffset;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
notfound:
|
||||
/*
|
||||
* If we started in the middle of the directory and failed
|
||||
* to find our target, we must check the beginning as well.
|
||||
*/
|
||||
if (numdirpasses == 2) {
|
||||
numdirpasses--;
|
||||
dp->i_offset = 0;
|
||||
endsearch = dp->i_diroff;
|
||||
goto searchloop;
|
||||
}
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
if (nameiop == CREATE || nameiop == RENAME)
|
||||
return (EROFS);
|
||||
return (ENOENT);
|
||||
|
||||
found:
|
||||
if (numdirpasses == 2)
|
||||
nchstats.ncs_pass2++;
|
||||
|
||||
/*
|
||||
* Found component in pathname.
|
||||
* If the final component of path name, save information
|
||||
* in the cache as to where the entry was found.
|
||||
*/
|
||||
if ((flags & ISLASTCN) && nameiop == LOOKUP)
|
||||
dp->i_diroff = dp->i_offset;
|
||||
|
||||
/*
|
||||
* Step through the translation in the name. We do not `iput' the
|
||||
* directory because we may need it again if a symbolic link
|
||||
* is relative to the current directory. Instead we save it
|
||||
* unlocked as "pdp". We must get the target inode before unlocking
|
||||
* the directory to insure that the inode will not be removed
|
||||
* before we get it. We prevent deadlock by always fetching
|
||||
* inodes from the root, moving down the directory tree. Thus
|
||||
* when following backward pointers ".." we must unlock the
|
||||
* parent directory before getting the requested directory.
|
||||
* There is a potential race condition here if both the current
|
||||
* and parent directories are removed before the `iget' for the
|
||||
* inode associated with ".." returns. We hope that this occurs
|
||||
* infrequently since we cannot avoid this race condition without
|
||||
* implementing a sophisticated deadlock detection algorithm.
|
||||
* Note also that this simple deadlock detection scheme will not
|
||||
* work if the filesystem has any hard links other than ".."
|
||||
* that point backwards in the directory structure.
|
||||
*/
|
||||
pdp = vdp;
|
||||
/*
|
||||
* If ino is different from dp->i_ino,
|
||||
* it's a relocated directory.
|
||||
*/
|
||||
if (flags & ISDOTDOT) {
|
||||
saved_ino = dp->i_ino;
|
||||
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
|
||||
error = cd9660_vget_internal(vdp->v_mount, saved_ino,
|
||||
LK_EXCLUSIVE, &tdp,
|
||||
saved_ino != ino, ep);
|
||||
brelse(bp);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
brelse(bp);
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
*vpp = vdp;
|
||||
} else {
|
||||
error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
|
||||
LK_EXCLUSIVE, &tdp,
|
||||
dp->i_ino != ino, ep);
|
||||
brelse(bp);
|
||||
if (error)
|
||||
return (error);
|
||||
*vpp = tdp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert name into cache if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return buffer with the contents of block "offset" from the beginning of
|
||||
* directory "ip". If "res" is non-zero, fill it in with a pointer to the
|
||||
* remaining space in the directory.
|
||||
*/
|
||||
int
|
||||
cd9660_blkatoff(vp, offset, res, bpp)
|
||||
struct vnode *vp;
|
||||
off_t offset;
|
||||
char **res;
|
||||
struct buf **bpp;
|
||||
{
|
||||
struct iso_node *ip;
|
||||
struct iso_mnt *imp;
|
||||
struct buf *bp;
|
||||
daddr_t lbn;
|
||||
int bsize, bshift, error;
|
||||
|
||||
ip = VTOI(vp);
|
||||
imp = ip->i_mnt;
|
||||
lbn = lblkno(imp, offset);
|
||||
bsize = blksize(imp, ip, lbn);
|
||||
bshift = imp->im_bshift;
|
||||
|
||||
if ((error = bread(vp, lbn, bsize, NOCRED, &bp)) != 0) {
|
||||
brelse(bp);
|
||||
*bpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* We must BMAP the buffer because the directory code may use b_blkno
|
||||
* to calculate the inode for certain types of directory entries.
|
||||
* We could get away with not doing it before we VMIO-backed the
|
||||
* directories because the buffers would get freed atomically with
|
||||
* the invalidation of their data. But with VMIO-backed buffers
|
||||
* the buffers may be freed and then later reconstituted - and the
|
||||
* reconstituted buffer will have no knowledge of b_blkno.
|
||||
*/
|
||||
if (bp->b_blkno == bp->b_lblkno) {
|
||||
bp->b_blkno = (ip->iso_start + bp->b_lblkno) << (bshift - DEV_BSHIFT);
|
||||
}
|
||||
|
||||
if (res)
|
||||
*res = (char *)bp->b_data + blkoff(imp, offset);
|
||||
*bpp = bp;
|
||||
return (0);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_mount.h 8.1 (Berkeley) 5/24/95
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Arguments to mount ISO 9660 filesystems.
|
||||
*/
|
||||
struct iso_args {
|
||||
char *fspec; /* block special device to mount */
|
||||
struct export_args export; /* network export info */
|
||||
int flags; /* mounting flags, see below */
|
||||
int ssector; /* starting sector, 0 for 1st session */
|
||||
char *cs_disk; /* disk charset for Joliet cs conversion */
|
||||
char *cs_local; /* local charset for Joliet cs conversion */
|
||||
};
|
||||
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
|
||||
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
|
||||
#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
|
||||
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext.*/
|
||||
#define ISOFSMNT_BROKENJOLIET 0x00000010/* allow broken Joliet disks */
|
||||
#define ISOFSMNT_KICONV 0x00000020 /* Use libiconv to convert chars */
|
@ -1,332 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1994, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_node.c 8.2 (Berkeley) 1/23/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
static unsigned cd9660_chars2ui(unsigned char *begin, int len);
|
||||
|
||||
/*
|
||||
* Last reference to an inode, write the inode out and if necessary,
|
||||
* truncate and deallocate the file.
|
||||
*/
|
||||
int
|
||||
cd9660_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct thread *td = ap->a_td;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
int error = 0;
|
||||
|
||||
if (prtactive && vrefcnt(vp) != 0)
|
||||
vprint("cd9660_inactive: pushing active", vp);
|
||||
|
||||
ip->i_flag = 0;
|
||||
/*
|
||||
* If we are done with the inode, reclaim it
|
||||
* so that it can be reused immediately.
|
||||
*/
|
||||
if (ip->inode.iso_mode == 0)
|
||||
vrecycle(vp, td);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
int
|
||||
cd9660_reclaim(ap)
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
|
||||
if (prtactive && vrefcnt(vp) != 0)
|
||||
vprint("cd9660_reclaim: pushing active", vp);
|
||||
/*
|
||||
* Destroy the vm object and flush associated pages.
|
||||
*/
|
||||
vnode_destroy_vobject(vp);
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
vfs_hash_remove(vp);
|
||||
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
if (ip->i_mnt->im_devvp)
|
||||
vrele(ip->i_mnt->im_devvp);
|
||||
FREE(vp->v_data, M_ISOFSNODE);
|
||||
vp->v_data = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* File attributes
|
||||
*/
|
||||
void
|
||||
cd9660_defattr(isodir, inop, bp, ftype)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
enum ISO_FTYPE ftype;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
/* high sierra does not have timezone data, flag is one byte ahead */
|
||||
if (isonum_711(ftype == ISO_FTYPE_HIGH_SIERRA?
|
||||
&isodir->date[6]: isodir->flags)&2) {
|
||||
inop->inode.iso_mode = S_IFDIR;
|
||||
/*
|
||||
* If we return 2, fts() will assume there are no subdirectories
|
||||
* (just links for the path and .), so instead we return 1.
|
||||
*/
|
||||
inop->inode.iso_links = 1;
|
||||
} else {
|
||||
inop->inode.iso_mode = S_IFREG;
|
||||
inop->inode.iso_links = 1;
|
||||
}
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
cd9660_blkatoff(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
ap = (struct iso_extended_attributes *)bp->b_data;
|
||||
|
||||
if (isonum_711(ap->version) == 1) {
|
||||
if (!(ap->perm[0]&0x40))
|
||||
inop->inode.iso_mode |= VEXEC >> 6;
|
||||
if (!(ap->perm[0]&0x10))
|
||||
inop->inode.iso_mode |= VREAD >> 6;
|
||||
if (!(ap->perm[0]&4))
|
||||
inop->inode.iso_mode |= VEXEC >> 3;
|
||||
if (!(ap->perm[0]&1))
|
||||
inop->inode.iso_mode |= VREAD >> 3;
|
||||
if (!(ap->perm[1]&0x40))
|
||||
inop->inode.iso_mode |= VEXEC;
|
||||
if (!(ap->perm[1]&0x10))
|
||||
inop->inode.iso_mode |= VREAD;
|
||||
inop->inode.iso_uid = isonum_723(ap->owner); /* what about 0? */
|
||||
inop->inode.iso_gid = isonum_723(ap->group); /* what about 0? */
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
inop->inode.iso_mode |= VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6;
|
||||
inop->inode.iso_uid = (uid_t)0;
|
||||
inop->inode.iso_gid = (gid_t)0;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Time stamps
|
||||
*/
|
||||
void
|
||||
cd9660_deftstamp(isodir,inop,bp,ftype)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
enum ISO_FTYPE ftype;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
cd9660_blkatoff(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
ap = (struct iso_extended_attributes *)bp->b_data;
|
||||
|
||||
if (ftype != ISO_FTYPE_HIGH_SIERRA
|
||||
&& isonum_711(ap->version) == 1) {
|
||||
if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
|
||||
cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
|
||||
if (!cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
|
||||
inop->inode.iso_ctime = inop->inode.iso_atime;
|
||||
if (!cd9660_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
cd9660_tstamp_conv7(isodir->date,&inop->inode.iso_ctime,ftype);
|
||||
inop->inode.iso_atime = inop->inode.iso_ctime;
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_tstamp_conv7(pi,pu,ftype)
|
||||
u_char *pi;
|
||||
struct timespec *pu;
|
||||
enum ISO_FTYPE ftype;
|
||||
{
|
||||
int crtime, days;
|
||||
int y, m, d, hour, minute, second, tz;
|
||||
|
||||
y = pi[0] + 1900;
|
||||
m = pi[1];
|
||||
d = pi[2];
|
||||
hour = pi[3];
|
||||
minute = pi[4];
|
||||
second = pi[5];
|
||||
if(ftype != ISO_FTYPE_HIGH_SIERRA)
|
||||
tz = pi[6];
|
||||
else
|
||||
/* original high sierra misses timezone data */
|
||||
tz = 0;
|
||||
|
||||
if (y < 1970) {
|
||||
pu->tv_sec = 0;
|
||||
pu->tv_nsec = 0;
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef ORIGINAL
|
||||
/* computes day number relative to Sept. 19th,1989 */
|
||||
/* don't even *THINK* about changing formula. It works! */
|
||||
days = 367*(y-1980)-7*(y+(m+9)/12)/4-3*((y+(m-9)/7)/100+1)/4+275*m/9+d-100;
|
||||
#else
|
||||
/*
|
||||
* Changed :-) to make it relative to Jan. 1st, 1970
|
||||
* and to disambiguate negative division
|
||||
*/
|
||||
days = 367*(y-1960)-7*(y+(m+9)/12)/4-3*((y+(m+9)/12-1)/100+1)/4+275*m/9+d-239;
|
||||
#endif
|
||||
crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second;
|
||||
|
||||
/* timezone offset is unreliable on some disks */
|
||||
if (-48 <= tz && tz <= 52)
|
||||
crtime -= tz * 15 * 60;
|
||||
}
|
||||
pu->tv_sec = crtime;
|
||||
pu->tv_nsec = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u_int
|
||||
cd9660_chars2ui(begin,len)
|
||||
u_char *begin;
|
||||
int len;
|
||||
{
|
||||
u_int rc;
|
||||
|
||||
for (rc = 0; --len >= 0;) {
|
||||
rc *= 10;
|
||||
rc += *begin++ - '0';
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_tstamp_conv17(pi,pu)
|
||||
u_char *pi;
|
||||
struct timespec *pu;
|
||||
{
|
||||
u_char buf[7];
|
||||
|
||||
/* year:"0001"-"9999" -> -1900 */
|
||||
buf[0] = cd9660_chars2ui(pi,4) - 1900;
|
||||
|
||||
/* month: " 1"-"12" -> 1 - 12 */
|
||||
buf[1] = cd9660_chars2ui(pi + 4,2);
|
||||
|
||||
/* day: " 1"-"31" -> 1 - 31 */
|
||||
buf[2] = cd9660_chars2ui(pi + 6,2);
|
||||
|
||||
/* hour: " 0"-"23" -> 0 - 23 */
|
||||
buf[3] = cd9660_chars2ui(pi + 8,2);
|
||||
|
||||
/* minute:" 0"-"59" -> 0 - 59 */
|
||||
buf[4] = cd9660_chars2ui(pi + 10,2);
|
||||
|
||||
/* second:" 0"-"59" -> 0 - 59 */
|
||||
buf[5] = cd9660_chars2ui(pi + 12,2);
|
||||
|
||||
/* difference of GMT */
|
||||
buf[6] = pi[16];
|
||||
|
||||
return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT);
|
||||
}
|
||||
|
||||
ino_t
|
||||
isodirino(isodir, imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ino_t ino;
|
||||
|
||||
ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
|
||||
<< imp->im_bshift;
|
||||
return (ino);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_node.h 8.6 (Berkeley) 5/14/95
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Theoretically, directories can be more than 2Gb in length,
|
||||
* however, in practice this seems unlikely. So, we define
|
||||
* the type doff_t as a long to keep down the cost of doing
|
||||
* lookup on a 32-bit machine. If you are porting to a 64-bit
|
||||
* architecture, you should make doff_t the same as off_t.
|
||||
*/
|
||||
#define doff_t long
|
||||
|
||||
typedef struct {
|
||||
struct timespec iso_atime; /* time of last access */
|
||||
struct timespec iso_mtime; /* time of last modification */
|
||||
struct timespec iso_ctime; /* time file changed */
|
||||
u_short iso_mode; /* files access mode and type */
|
||||
uid_t iso_uid; /* owner user id */
|
||||
gid_t iso_gid; /* owner group id */
|
||||
short iso_links; /* links of file */
|
||||
dev_t iso_rdev; /* Major/Minor number for special */
|
||||
} ISO_RRIP_INODE;
|
||||
|
||||
|
||||
struct iso_node {
|
||||
struct vnode *i_vnode; /* vnode associated with this inode */
|
||||
u_long i_flag; /* see below */
|
||||
ino_t i_number; /* the identity of the inode */
|
||||
/* we use the actual starting block of the file */
|
||||
struct iso_mnt *i_mnt; /* filesystem associated with this inode */
|
||||
struct lockf *i_lockf; /* head of byte-level lock list */
|
||||
doff_t i_endoff; /* end of useful stuff in directory */
|
||||
doff_t i_diroff; /* offset in dir, where we found last entry */
|
||||
doff_t i_offset; /* offset of free space in directory */
|
||||
ino_t i_ino; /* inode number of found directory */
|
||||
|
||||
long iso_extent; /* extent of file */
|
||||
unsigned long i_size;
|
||||
long iso_start; /* actual start of data of file (may be different */
|
||||
/* from iso_extent, if file has extended attributes) */
|
||||
ISO_RRIP_INODE inode;
|
||||
};
|
||||
|
||||
#define i_forw i_chain[0]
|
||||
#define i_back i_chain[1]
|
||||
|
||||
/* flags */
|
||||
#define IN_ACCESS 0x0020 /* inode access time to be updated */
|
||||
|
||||
#define VTOI(vp) ((struct iso_node *)(vp)->v_data)
|
||||
#define ITOV(ip) ((ip)->i_vnode)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_ISOFSMNT);
|
||||
MALLOC_DECLARE(M_ISOFSNODE);
|
||||
#endif
|
||||
|
||||
struct buf;
|
||||
struct vop_bmap_args;
|
||||
struct vop_cachedlookup_args;
|
||||
struct vop_inactive_args;
|
||||
struct vop_reclaim_args;
|
||||
|
||||
/*
|
||||
* Prototypes for ISOFS vnode operations
|
||||
*/
|
||||
int cd9660_lookup(struct vop_cachedlookup_args *);
|
||||
int cd9660_inactive(struct vop_inactive_args *);
|
||||
int cd9660_reclaim(struct vop_reclaim_args *);
|
||||
int cd9660_bmap(struct vop_bmap_args *);
|
||||
int cd9660_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp);
|
||||
|
||||
void cd9660_defattr(struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *, enum ISO_FTYPE);
|
||||
void cd9660_deftstamp(struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *, enum ISO_FTYPE);
|
||||
int cd9660_tstamp_conv7(u_char *, struct timespec *, enum ISO_FTYPE);
|
||||
int cd9660_tstamp_conv17(u_char *, struct timespec *);
|
||||
|
||||
#endif /* _KERNEL */
|
@ -1,715 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_rrip.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
|
||||
typedef int rrt_func_t(void *, ISO_RRIP_ANALYZE *ana);
|
||||
|
||||
typedef struct {
|
||||
char type[2];
|
||||
rrt_func_t *func;
|
||||
void (*func2)(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana);
|
||||
int result;
|
||||
} RRIP_TABLE;
|
||||
|
||||
static int cd9660_rrip_altname(ISO_RRIP_ALTNAME *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_attr(ISO_RRIP_ATTR *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_cont(ISO_RRIP_CONT *p, ISO_RRIP_ANALYZE *ana);
|
||||
static void cd9660_rrip_defattr(struct iso_directory_record *isodir,
|
||||
ISO_RRIP_ANALYZE *ana);
|
||||
static void cd9660_rrip_defname(struct iso_directory_record *isodir,
|
||||
ISO_RRIP_ANALYZE *ana);
|
||||
static void cd9660_rrip_deftstamp(struct iso_directory_record *isodir,
|
||||
ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_device(ISO_RRIP_DEVICE *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_extref(ISO_RRIP_EXTREF *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_idflag(ISO_RRIP_IDFLAG *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_loop(struct iso_directory_record *isodir,
|
||||
ISO_RRIP_ANALYZE *ana, RRIP_TABLE *table);
|
||||
static int cd9660_rrip_pclink(ISO_RRIP_CLINK *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_reldir(ISO_RRIP_RELDIR *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_slink(ISO_RRIP_SLINK *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_stop(ISO_SUSP_HEADER *p, ISO_RRIP_ANALYZE *ana);
|
||||
static int cd9660_rrip_tstamp(ISO_RRIP_TSTAMP *p, ISO_RRIP_ANALYZE *ana);
|
||||
|
||||
/*
|
||||
* POSIX file attribute
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_attr(p,ana)
|
||||
ISO_RRIP_ATTR *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ana->inop->inode.iso_mode = isonum_733(p->mode);
|
||||
ana->inop->inode.iso_uid = isonum_733(p->uid);
|
||||
ana->inop->inode.iso_gid = isonum_733(p->gid);
|
||||
ana->inop->inode.iso_links = isonum_733(p->links);
|
||||
ana->fields &= ~ISO_SUSP_ATTR;
|
||||
return ISO_SUSP_ATTR;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_defattr(isodir,ana)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
/* But this is a required field! */
|
||||
printf("RRIP without PX field?\n");
|
||||
cd9660_defattr(isodir,ana->inop,NULL,ISO_FTYPE_RRIP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Symbolic Links
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_slink(p,ana)
|
||||
ISO_RRIP_SLINK *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ISO_RRIP_SLINK_COMPONENT *pcomp;
|
||||
ISO_RRIP_SLINK_COMPONENT *pcompe;
|
||||
int len, wlen, cont;
|
||||
char *outbuf, *inbuf;
|
||||
|
||||
pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
|
||||
pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
|
||||
len = *ana->outlen;
|
||||
outbuf = ana->outbuf;
|
||||
cont = ana->cont;
|
||||
|
||||
/*
|
||||
* Gathering a Symbolic name from each component with path
|
||||
*/
|
||||
for (;
|
||||
pcomp < pcompe;
|
||||
pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ
|
||||
+ isonum_711(pcomp->clen))) {
|
||||
|
||||
if (!cont) {
|
||||
if (len < ana->maxlen) {
|
||||
len++;
|
||||
*outbuf++ = '/';
|
||||
}
|
||||
}
|
||||
cont = 0;
|
||||
|
||||
inbuf = "..";
|
||||
wlen = 0;
|
||||
|
||||
switch (*pcomp->cflag) {
|
||||
|
||||
case ISO_SUSP_CFLAG_CURRENT:
|
||||
/* Inserting Current */
|
||||
wlen = 1;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_PARENT:
|
||||
/* Inserting Parent */
|
||||
wlen = 2;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_ROOT:
|
||||
/* Inserting slash for ROOT */
|
||||
/* Double slash, nothing really to do here. */
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_VOLROOT:
|
||||
/* Inserting a mount point i.e. "/cdrom" */
|
||||
/* same as above */
|
||||
outbuf -= len;
|
||||
len = 0;
|
||||
inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
|
||||
wlen = strlen(inbuf);
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_HOST:
|
||||
/* Inserting hostname i.e. "kurt.tools.de" */
|
||||
inbuf = hostname;
|
||||
wlen = strlen(hostname);
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_CONTINUE:
|
||||
cont = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
/* Inserting component */
|
||||
wlen = isonum_711(pcomp->clen);
|
||||
inbuf = pcomp->name;
|
||||
break;
|
||||
default:
|
||||
printf("RRIP with incorrect flags?");
|
||||
wlen = ana->maxlen + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (len + wlen > ana->maxlen) {
|
||||
/* indicate error to caller */
|
||||
ana->cont = 1;
|
||||
ana->fields = 0;
|
||||
ana->outbuf -= *ana->outlen;
|
||||
*ana->outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bcopy(inbuf,outbuf,wlen);
|
||||
outbuf += wlen;
|
||||
len += wlen;
|
||||
|
||||
}
|
||||
ana->outbuf = outbuf;
|
||||
*ana->outlen = len;
|
||||
ana->cont = cont;
|
||||
|
||||
if (!isonum_711(p->flags)) {
|
||||
ana->fields &= ~ISO_SUSP_SLINK;
|
||||
return ISO_SUSP_SLINK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Alternate name
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_altname(p,ana)
|
||||
ISO_RRIP_ALTNAME *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
char *inbuf;
|
||||
int wlen;
|
||||
int cont;
|
||||
|
||||
inbuf = "..";
|
||||
wlen = 0;
|
||||
cont = 0;
|
||||
|
||||
switch (*p->flags) {
|
||||
case ISO_SUSP_CFLAG_CURRENT:
|
||||
/* Inserting Current */
|
||||
wlen = 1;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_PARENT:
|
||||
/* Inserting Parent */
|
||||
wlen = 2;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_HOST:
|
||||
/* Inserting hostname i.e. "kurt.tools.de" */
|
||||
inbuf = hostname;
|
||||
wlen = strlen(hostname);
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_CONTINUE:
|
||||
cont = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
/* Inserting component */
|
||||
wlen = isonum_711(p->h.length) - 5;
|
||||
inbuf = (char *)p + 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("RRIP with incorrect NM flags?\n");
|
||||
wlen = ana->maxlen + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*ana->outlen += wlen) > ana->maxlen) {
|
||||
/* treat as no name field */
|
||||
ana->fields &= ~ISO_SUSP_ALTNAME;
|
||||
ana->outbuf -= *ana->outlen - wlen;
|
||||
*ana->outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bcopy(inbuf,ana->outbuf,wlen);
|
||||
ana->outbuf += wlen;
|
||||
|
||||
if (!cont) {
|
||||
ana->fields &= ~ISO_SUSP_ALTNAME;
|
||||
return ISO_SUSP_ALTNAME;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_defname(isodir,ana)
|
||||
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;
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
/* outlen is 1 already */
|
||||
strcpy(ana->outbuf,"..");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parent or Child Link
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_pclink(p,ana)
|
||||
ISO_RRIP_CLINK *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
*ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
|
||||
ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK);
|
||||
return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Relocated directory
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_reldir(p,ana)
|
||||
ISO_RRIP_RELDIR *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
/* special hack to make caller aware of RE field */
|
||||
*ana->outlen = 0;
|
||||
ana->fields = 0;
|
||||
return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_rrip_tstamp(p,ana)
|
||||
ISO_RRIP_TSTAMP *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
u_char *ptime;
|
||||
|
||||
ptime = p->time;
|
||||
|
||||
/* Check a format of time stamp (7bytes/17bytes) */
|
||||
if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) {
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
|
||||
ptime += 7;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
|
||||
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime,
|
||||
ISO_FTYPE_RRIP);
|
||||
ptime += 7;
|
||||
} else
|
||||
bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
|
||||
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime,
|
||||
ISO_FTYPE_RRIP);
|
||||
ptime += 7;
|
||||
} else
|
||||
ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
|
||||
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime,
|
||||
ISO_FTYPE_RRIP);
|
||||
else
|
||||
ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
|
||||
|
||||
} else {
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
|
||||
ptime += 17;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
|
||||
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime);
|
||||
ptime += 17;
|
||||
} else
|
||||
bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
|
||||
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime);
|
||||
ptime += 17;
|
||||
} else
|
||||
ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
|
||||
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime);
|
||||
else
|
||||
ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
|
||||
|
||||
}
|
||||
ana->fields &= ~ISO_SUSP_TSTAMP;
|
||||
return ISO_SUSP_TSTAMP;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_deftstamp(isodir,ana)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
cd9660_deftstamp(isodir,ana->inop,NULL,ISO_FTYPE_RRIP);
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX device modes
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_device(p,ana)
|
||||
ISO_RRIP_DEVICE *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
u_int high, low;
|
||||
|
||||
high = isonum_733(p->dev_t_high);
|
||||
low = isonum_733(p->dev_t_low);
|
||||
|
||||
if (high == 0)
|
||||
ana->inop->inode.iso_rdev = makedev(umajor(low), uminor(low));
|
||||
else
|
||||
ana->inop->inode.iso_rdev = makedev(high, uminor(low));
|
||||
ana->fields &= ~ISO_SUSP_DEVICE;
|
||||
return ISO_SUSP_DEVICE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flag indicating
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_idflag(p,ana)
|
||||
ISO_RRIP_IDFLAG *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */
|
||||
/* special handling of RE field */
|
||||
if (ana->fields&ISO_SUSP_RELDIR)
|
||||
return cd9660_rrip_reldir(/* XXX */ (ISO_RRIP_RELDIR *)p,ana);
|
||||
|
||||
return ISO_SUSP_IDFLAG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continuation pointer
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_cont(p,ana)
|
||||
ISO_RRIP_CONT *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ana->iso_ce_blk = isonum_733(p->location);
|
||||
ana->iso_ce_off = isonum_733(p->offset);
|
||||
ana->iso_ce_len = isonum_733(p->length);
|
||||
return ISO_SUSP_CONT;
|
||||
}
|
||||
|
||||
/*
|
||||
* System Use end
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_stop(p,ana)
|
||||
ISO_SUSP_HEADER *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
return ISO_SUSP_STOP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension reference
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_extref(p,ana)
|
||||
ISO_RRIP_EXTREF *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
if (isonum_711(p->len_id) != 10
|
||||
|| bcmp((char *)p + 8,"RRIP_1991A",10)
|
||||
|| isonum_711(p->version) != 1)
|
||||
return 0;
|
||||
ana->fields &= ~ISO_SUSP_EXTREF;
|
||||
return ISO_SUSP_EXTREF;
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_rrip_loop(isodir,ana,table)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
RRIP_TABLE *table;
|
||||
{
|
||||
RRIP_TABLE *ptable;
|
||||
ISO_SUSP_HEADER *phead;
|
||||
ISO_SUSP_HEADER *pend;
|
||||
struct buf *bp = NULL;
|
||||
char *pwhead;
|
||||
u_short c;
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Note: If name length is odd,
|
||||
* it will be padding 1 byte after the name
|
||||
*/
|
||||
pwhead = isodir->name + isonum_711(isodir->name_len);
|
||||
if (!(isonum_711(isodir->name_len)&1))
|
||||
pwhead++;
|
||||
isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL,
|
||||
ana->imp->im_flags, ana->imp->im_d2l);
|
||||
|
||||
/* If it's not the '.' entry of the root dir obey SP field */
|
||||
if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
|
||||
pwhead += ana->imp->rr_skip;
|
||||
else
|
||||
pwhead += ana->imp->rr_skip0;
|
||||
|
||||
phead = (ISO_SUSP_HEADER *)pwhead;
|
||||
pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
|
||||
|
||||
result = 0;
|
||||
while (1) {
|
||||
ana->iso_ce_len = 0;
|
||||
/*
|
||||
* Note: "pend" should be more than one SUSP header
|
||||
*/
|
||||
while (pend >= phead + 1) {
|
||||
if (isonum_711(phead->version) == 1) {
|
||||
for (ptable = table; ptable->func; ptable++) {
|
||||
if (*phead->type == *ptable->type
|
||||
&& phead->type[1] == ptable->type[1]) {
|
||||
result |= ptable->func(phead,ana);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ana->fields)
|
||||
break;
|
||||
}
|
||||
if (result&ISO_SUSP_STOP) {
|
||||
result &= ~ISO_SUSP_STOP;
|
||||
break;
|
||||
}
|
||||
/* plausibility check */
|
||||
if (isonum_711(phead->length) < sizeof(*phead))
|
||||
break;
|
||||
/*
|
||||
* move to next SUSP
|
||||
* Hopefully this works with newer versions, too
|
||||
*/
|
||||
phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
|
||||
}
|
||||
|
||||
if (ana->fields && ana->iso_ce_len) {
|
||||
if (ana->iso_ce_blk >= ana->imp->volume_space_size
|
||||
|| ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
|
||||
|| bread(ana->imp->im_devvp,
|
||||
ana->iso_ce_blk <<
|
||||
(ana->imp->im_bshift - DEV_BSHIFT),
|
||||
ana->imp->logical_block_size, NOCRED, &bp))
|
||||
/* what to do now? */
|
||||
break;
|
||||
phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
|
||||
pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
/*
|
||||
* If we don't find the Basic SUSP stuffs, just set default value
|
||||
* (attribute/time stamp)
|
||||
*/
|
||||
for (ptable = table; ptable->func2; ptable++)
|
||||
if (!(ptable->result&result))
|
||||
ptable->func2(isodir,ana);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Attributes.
|
||||
*/
|
||||
/*
|
||||
* XXX the casts are bogus but will do for now.
|
||||
*/
|
||||
#define BC (rrt_func_t *)
|
||||
static RRIP_TABLE rrip_table_analyze[] = {
|
||||
{ "PX", BC cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR },
|
||||
{ "TF", BC cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP },
|
||||
{ "PN", BC cd9660_rrip_device, 0, ISO_SUSP_DEVICE },
|
||||
{ "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_analyze(isodir,inop,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
analyze.inop = inop;
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE;
|
||||
|
||||
return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Alternate Name.
|
||||
*/
|
||||
static RRIP_TABLE rrip_table_getname[] = {
|
||||
{ "NM", BC cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
|
||||
{ "CL", BC cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
|
||||
{ "PL", BC cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
|
||||
{ "RE", BC cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR },
|
||||
{ "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
char *outbuf;
|
||||
u_short *outlen;
|
||||
ino_t *inump;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
RRIP_TABLE *tab;
|
||||
u_short c;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
analyze.maxlen = NAME_MAX;
|
||||
analyze.inump = inump;
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
|
||||
*outlen = 0;
|
||||
|
||||
isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
|
||||
imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l);
|
||||
tab = rrip_table_getname;
|
||||
if (c == 0 || c == 1) {
|
||||
cd9660_rrip_defname(isodir,&analyze);
|
||||
|
||||
analyze.fields &= ~ISO_SUSP_ALTNAME;
|
||||
tab++;
|
||||
}
|
||||
|
||||
return cd9660_rrip_loop(isodir,&analyze,tab);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Symbolic Link.
|
||||
*/
|
||||
static RRIP_TABLE rrip_table_getsymname[] = {
|
||||
{ "SL", BC cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
|
||||
{ "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_getsymname(isodir,outbuf,outlen,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
char *outbuf;
|
||||
u_short *outlen;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
*outlen = 0;
|
||||
analyze.maxlen = MAXPATHLEN;
|
||||
analyze.cont = 1; /* don't start with a slash */
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_SLINK;
|
||||
|
||||
return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK);
|
||||
}
|
||||
|
||||
static RRIP_TABLE rrip_table_extref[] = {
|
||||
{ "ER", BC cd9660_rrip_extref, 0, ISO_SUSP_EXTREF },
|
||||
{ "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Check for Rock Ridge Extension and return offset of its fields.
|
||||
* Note: We insist on the ER field.
|
||||
*/
|
||||
int
|
||||
cd9660_rrip_offset(isodir,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_OFFSET *p;
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
imp->rr_skip0 = 0;
|
||||
p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
|
||||
if (bcmp(p,"SP\7\1\276\357",6)) {
|
||||
/* Maybe, it's a CDROM XA disc? */
|
||||
imp->rr_skip0 = 15;
|
||||
p = (ISO_RRIP_OFFSET *)((char *)p + 15);
|
||||
if (bcmp(p,"SP\7\1\276\357",6))
|
||||
return -1;
|
||||
}
|
||||
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_EXTREF;
|
||||
if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF))
|
||||
return -1;
|
||||
|
||||
return isonum_711(p->skip);
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char type [ISODCL ( 0, 1)];
|
||||
u_char length [ISODCL ( 2, 2)]; /* 711 */
|
||||
u_char version [ISODCL ( 3, 3)];
|
||||
} ISO_SUSP_HEADER;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char mode [ISODCL ( 4, 11)]; /* 733 */
|
||||
char links [ISODCL ( 12, 19)]; /* 733 */
|
||||
char uid [ISODCL ( 20, 27)]; /* 733 */
|
||||
char gid [ISODCL ( 28, 35)]; /* 733 */
|
||||
} ISO_RRIP_ATTR;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char dev_t_high [ISODCL ( 4, 11)]; /* 733 */
|
||||
char dev_t_low [ISODCL ( 12, 19)]; /* 733 */
|
||||
} ISO_RRIP_DEVICE;
|
||||
|
||||
#define ISO_SUSP_CFLAG_CONTINUE 0x01
|
||||
#define ISO_SUSP_CFLAG_CURRENT 0x02
|
||||
#define ISO_SUSP_CFLAG_PARENT 0x04
|
||||
#define ISO_SUSP_CFLAG_ROOT 0x08
|
||||
#define ISO_SUSP_CFLAG_VOLROOT 0x10
|
||||
#define ISO_SUSP_CFLAG_HOST 0x20
|
||||
|
||||
typedef struct {
|
||||
u_char cflag [ISODCL ( 1, 1)];
|
||||
u_char clen [ISODCL ( 2, 2)];
|
||||
u_char name [1]; /* XXX */
|
||||
} ISO_RRIP_SLINK_COMPONENT;
|
||||
#define ISO_RRIP_SLSIZ 2
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
u_char component [ISODCL ( 5, 5)];
|
||||
} ISO_RRIP_SLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char flags [ISODCL ( 4, 4)];
|
||||
} ISO_RRIP_ALTNAME;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char dir_loc [ISODCL ( 4, 11)]; /* 733 */
|
||||
} ISO_RRIP_CLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char dir_loc [ISODCL ( 4, 11)]; /* 733 */
|
||||
} ISO_RRIP_PLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
} ISO_RRIP_RELDIR;
|
||||
|
||||
#define ISO_SUSP_TSTAMP_FORM17 0x80
|
||||
#define ISO_SUSP_TSTAMP_FORM7 0x00
|
||||
#define ISO_SUSP_TSTAMP_CREAT 0x01
|
||||
#define ISO_SUSP_TSTAMP_MODIFY 0x02
|
||||
#define ISO_SUSP_TSTAMP_ACCESS 0x04
|
||||
#define ISO_SUSP_TSTAMP_ATTR 0x08
|
||||
#define ISO_SUSP_TSTAMP_BACKUP 0x10
|
||||
#define ISO_SUSP_TSTAMP_EXPIRE 0x20
|
||||
#define ISO_SUSP_TSTAMP_EFFECT 0x40
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
u_char time [ISODCL ( 5, 5)];
|
||||
} ISO_RRIP_TSTAMP;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
} ISO_RRIP_IDFLAG;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char len_id [ISODCL ( 4, 4)];
|
||||
char len_des [ISODCL ( 5, 5)];
|
||||
char len_src [ISODCL ( 6, 6)];
|
||||
char version [ISODCL ( 7, 7)];
|
||||
} ISO_RRIP_EXTREF;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char check [ISODCL ( 4, 5)];
|
||||
char skip [ISODCL ( 6, 6)];
|
||||
} ISO_RRIP_OFFSET;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char location [ISODCL ( 4, 11)];
|
||||
char offset [ISODCL ( 12, 19)];
|
||||
char length [ISODCL ( 20, 27)];
|
||||
} ISO_RRIP_CONT;
|
@ -1,243 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp). Joliet support was added by
|
||||
* Joachim Kuebart (joki@kuebart.stuttgart.netsurf.de).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
extern struct iconv_functions *cd9660_iconv;
|
||||
|
||||
/*
|
||||
* Get one character out of an iso filename
|
||||
* Obey joliet_level
|
||||
* Return number of bytes consumed
|
||||
*/
|
||||
int
|
||||
isochar(isofn, isoend, joliet_level, c, clen, flags, handle)
|
||||
u_char *isofn;
|
||||
u_char *isoend;
|
||||
int joliet_level;
|
||||
u_short *c;
|
||||
int *clen;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char inbuf[3], outbuf[3], *inp, *outp;
|
||||
|
||||
*c = *isofn++;
|
||||
if (clen) *clen = 1;
|
||||
if (joliet_level == 0 || isofn == isoend)
|
||||
/* (00) and (01) are one byte in Joliet, too */
|
||||
return 1;
|
||||
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
i = j = len = 2;
|
||||
inbuf[0]=(char)*(isofn - 1);
|
||||
inbuf[1]=(char)*isofn;
|
||||
inbuf[2]='\0';
|
||||
inp = inbuf;
|
||||
outp = outbuf;
|
||||
cd9660_iconv->convchr(handle, (const char **)&inp, &i, &outp, &j);
|
||||
len -= j;
|
||||
if (clen) *clen = len;
|
||||
*c = '\0';
|
||||
while(len--)
|
||||
*c |= (*(outp - len - 1) & 0xff) << (len << 3);
|
||||
} else {
|
||||
switch (*c) {
|
||||
default:
|
||||
*c = '?';
|
||||
break;
|
||||
case '\0':
|
||||
*c = *isofn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* translate and compare a filename
|
||||
* returns (fn - isofn)
|
||||
* Note: Version number plus ';' may be omitted.
|
||||
*/
|
||||
int
|
||||
isofncmp(fn, fnlen, isofn, isolen, joliet_level, flags, handle, lhandle)
|
||||
u_char *fn;
|
||||
int fnlen;
|
||||
u_char *isofn;
|
||||
int isolen;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
void *lhandle;
|
||||
{
|
||||
int i, j;
|
||||
u_short c, d;
|
||||
u_char *fnend = fn + fnlen, *isoend = isofn + isolen;
|
||||
|
||||
for (; fn < fnend; ) {
|
||||
d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle);
|
||||
if (isofn == isoend)
|
||||
return d;
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
if (c == ';') {
|
||||
if (d != ';')
|
||||
return d;
|
||||
for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') {
|
||||
if (*fn < '0' || *fn > '9') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (j = 0; isofn != isoend; j = j * 10 + c - '0')
|
||||
isofn += isochar(isofn, isoend,
|
||||
joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
return i - j;
|
||||
}
|
||||
if (c != d) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (c + ('a' - 'A') != d) {
|
||||
if (d >= 'a' && d <= 'z')
|
||||
return d - ('a' - 'A') - c;
|
||||
else
|
||||
return d - c;
|
||||
}
|
||||
} else
|
||||
return d - c;
|
||||
}
|
||||
}
|
||||
if (isofn != isoend) {
|
||||
isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
|
||||
switch (c) {
|
||||
default:
|
||||
return -c;
|
||||
case '.':
|
||||
if (isofn != isoend) {
|
||||
isochar(isofn, isoend, joliet_level, &c,
|
||||
NULL, flags, handle);
|
||||
if (c == ';')
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
case ';':
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* translate a filename of length > 0
|
||||
*/
|
||||
void
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level, flags, handle)
|
||||
u_char *infn;
|
||||
int infnlen;
|
||||
u_char *outfn;
|
||||
u_short *outfnlen;
|
||||
int original;
|
||||
int assoc;
|
||||
int joliet_level;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
u_short c, d = '\0';
|
||||
u_char *outp = outfn, *infnend = infn + infnlen;
|
||||
int clen;
|
||||
|
||||
if (assoc) {
|
||||
*outp++ = ASSOCCHAR;
|
||||
}
|
||||
for (; infn != infnend; ) {
|
||||
infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle);
|
||||
|
||||
if (!original && !joliet_level && c >= 'A' && c <= 'Z')
|
||||
c += ('a' - 'A');
|
||||
else if (!original && c == ';') {
|
||||
outp -= (d == '.');
|
||||
break;
|
||||
}
|
||||
d = c;
|
||||
while(clen--)
|
||||
*outp++ = c >> (clen << 3);
|
||||
}
|
||||
*outfnlen = outp - outfn;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as sgetrune(3)
|
||||
*/
|
||||
u_short
|
||||
sgetrune(string, n, result, flags, handle)
|
||||
const char *string;
|
||||
size_t n;
|
||||
char const **result;
|
||||
int flags;
|
||||
void *handle;
|
||||
{
|
||||
size_t i, j, len;
|
||||
char outbuf[3], *outp;
|
||||
u_short c = '\0';
|
||||
|
||||
len = i = (n < 2) ? n : 2;
|
||||
j = 2;
|
||||
outp = outbuf;
|
||||
|
||||
if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cd9660_iconv->convchr(handle, (const char **)&string,
|
||||
&i, &outp, &j);
|
||||
len -= i;
|
||||
} else {
|
||||
len = 1;
|
||||
string++;
|
||||
}
|
||||
|
||||
if (result) *result = string;
|
||||
while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3);
|
||||
return (c);
|
||||
}
|
@ -1,848 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/cdio.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/iconv.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
#include <geom/geom_vfs.h>
|
||||
|
||||
MALLOC_DEFINE(M_ISOFSMNT, "isofs_mount", "ISOFS mount structure");
|
||||
MALLOC_DEFINE(M_ISOFSNODE, "isofs_node", "ISOFS vnode private part");
|
||||
|
||||
struct iconv_functions *cd9660_iconv = NULL;
|
||||
|
||||
static vfs_mount_t cd9660_mount;
|
||||
static vfs_cmount_t cd9660_cmount;
|
||||
static vfs_unmount_t cd9660_unmount;
|
||||
static vfs_root_t cd9660_root;
|
||||
static vfs_statfs_t cd9660_statfs;
|
||||
static vfs_vget_t cd9660_vget;
|
||||
static vfs_fhtovp_t cd9660_fhtovp;
|
||||
static vfs_vptofh_t cd9660_vptofh;
|
||||
|
||||
static struct vfsops cd9660_vfsops = {
|
||||
.vfs_fhtovp = cd9660_fhtovp,
|
||||
.vfs_mount = cd9660_mount,
|
||||
.vfs_cmount = cd9660_cmount,
|
||||
.vfs_root = cd9660_root,
|
||||
.vfs_statfs = cd9660_statfs,
|
||||
.vfs_unmount = cd9660_unmount,
|
||||
.vfs_vget = cd9660_vget,
|
||||
.vfs_vptofh = cd9660_vptofh,
|
||||
};
|
||||
VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY);
|
||||
MODULE_VERSION(cd9660, 1);
|
||||
|
||||
static int iso_mountfs(struct vnode *devvp, struct mount *mp,
|
||||
struct thread *td);
|
||||
|
||||
/*
|
||||
* VFS Operations.
|
||||
*/
|
||||
|
||||
static int
|
||||
cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
|
||||
{
|
||||
struct iso_args args;
|
||||
int error;
|
||||
|
||||
error = copyin(data, &args, sizeof args);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
|
||||
ma = mount_arg(ma, "export", &args.export, sizeof args.export);
|
||||
ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
|
||||
ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
|
||||
ma = mount_argf(ma, "ssector", "%u", args.ssector);
|
||||
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NORRIP), "norrip");
|
||||
ma = mount_argb(ma, args.flags & ISOFSMNT_GENS, "nogens");
|
||||
ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "noextatt");
|
||||
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NOJOLIET), "nojoliet");
|
||||
ma = mount_argb(ma,
|
||||
args.flags & ISOFSMNT_BROKENJOLIET, "nobrokenjoliet");
|
||||
ma = mount_argb(ma, args.flags & ISOFSMNT_KICONV, "nokiconv");
|
||||
|
||||
error = kernel_mount(ma, flags);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_mount(struct mount *mp, struct thread *td)
|
||||
{
|
||||
struct vnode *devvp;
|
||||
char *fspec;
|
||||
int error;
|
||||
mode_t accessmode;
|
||||
struct nameidata ndp;
|
||||
struct iso_mnt *imp = 0;
|
||||
|
||||
/*
|
||||
* Unconditionally mount as read-only.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
imp = VFSTOISOFS(mp);
|
||||
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0))
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Not an update, or updating the name: look up the name
|
||||
* and verify that it refers to a sensible block device.
|
||||
*/
|
||||
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, td);
|
||||
if ((error = namei(&ndp)))
|
||||
return (error);
|
||||
NDFREE(&ndp, NDF_ONLY_PNBUF);
|
||||
devvp = ndp.ni_vp;
|
||||
|
||||
if (!vn_isdisk(devvp, &error)) {
|
||||
vrele(devvp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that user has necessary permissions on the device,
|
||||
* or has superuser abilities
|
||||
*/
|
||||
accessmode = VREAD;
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
|
||||
if (error)
|
||||
error = priv_check(td, PRIV_VFS_MOUNT_PERM);
|
||||
if (error) {
|
||||
vput(devvp);
|
||||
return (error);
|
||||
}
|
||||
VOP_UNLOCK(devvp, 0, td);
|
||||
|
||||
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
|
||||
error = iso_mountfs(devvp, mp, td);
|
||||
} else {
|
||||
if (devvp != imp->im_devvp)
|
||||
error = EINVAL; /* needs translation */
|
||||
else
|
||||
vrele(devvp);
|
||||
}
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
return error;
|
||||
}
|
||||
vfs_mountedfrom(mp, fspec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common code for mount and mountroot
|
||||
*/
|
||||
static int
|
||||
iso_mountfs(devvp, mp, td)
|
||||
struct vnode *devvp;
|
||||
struct mount *mp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct iso_mnt *isomp = (struct iso_mnt *)0;
|
||||
struct buf *bp = NULL;
|
||||
struct buf *pribp = NULL, *supbp = NULL;
|
||||
struct cdev *dev = devvp->v_rdev;
|
||||
int error = EINVAL;
|
||||
int high_sierra = 0;
|
||||
int iso_bsize;
|
||||
int iso_blknum;
|
||||
int joliet_level;
|
||||
struct iso_volume_descriptor *vdp = 0;
|
||||
struct iso_primary_descriptor *pri = NULL;
|
||||
struct iso_sierra_primary_descriptor *pri_sierra = NULL;
|
||||
struct iso_supplementary_descriptor *sup = NULL;
|
||||
struct iso_directory_record *rootp;
|
||||
int logical_block_size, ssector;
|
||||
struct g_consumer *cp;
|
||||
struct bufobj *bo;
|
||||
char *cs_local, *cs_disk;
|
||||
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
error = g_vfs_open(devvp, &cp, "cd9660", 0);
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
VOP_UNLOCK(devvp, 0, td);
|
||||
if (error)
|
||||
return error;
|
||||
if (devvp->v_rdev->si_iosize_max != 0)
|
||||
mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
|
||||
if (mp->mnt_iosize_max > MAXPHYS)
|
||||
mp->mnt_iosize_max = MAXPHYS;
|
||||
|
||||
bo = &devvp->v_bufobj;
|
||||
bo->bo_private = cp;
|
||||
bo->bo_ops = g_vfs_bufops;
|
||||
|
||||
/* This is the "logical sector size". The standard says this
|
||||
* should be 2048 or the physical sector size on the device,
|
||||
* whichever is greater.
|
||||
*/
|
||||
if ((ISO_DEFAULT_BLOCK_SIZE % cp->provider->sectorsize) != 0) {
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
g_vfs_close(cp, td);
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
iso_bsize = cp->provider->sectorsize;
|
||||
|
||||
joliet_level = 0;
|
||||
if (1 != vfs_scanopt(mp->mnt_optnew, "ssector", "%d", &ssector))
|
||||
ssector = 0;
|
||||
for (iso_blknum = 16 + ssector;
|
||||
iso_blknum < 100 + ssector;
|
||||
iso_blknum++) {
|
||||
if ((error = bread(devvp, iso_blknum * btodb(ISO_DEFAULT_BLOCK_SIZE),
|
||||
iso_bsize, NOCRED, &bp)) != 0)
|
||||
goto out;
|
||||
|
||||
vdp = (struct iso_volume_descriptor *)bp->b_data;
|
||||
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
|
||||
if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
|
||||
sizeof vdp->id) != 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
} else
|
||||
high_sierra = 1;
|
||||
}
|
||||
switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){
|
||||
case ISO_VD_PRIMARY:
|
||||
if (pribp == NULL) {
|
||||
pribp = bp;
|
||||
bp = NULL;
|
||||
pri = (struct iso_primary_descriptor *)vdp;
|
||||
pri_sierra =
|
||||
(struct iso_sierra_primary_descriptor *)vdp;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISO_VD_SUPPLEMENTARY:
|
||||
if (supbp == NULL) {
|
||||
supbp = bp;
|
||||
bp = NULL;
|
||||
sup = (struct iso_supplementary_descriptor *)vdp;
|
||||
|
||||
if (!vfs_flagopt(mp->mnt_optnew, "nojoliet", NULL, 0)) {
|
||||
if (bcmp(sup->escape, "%/@", 3) == 0)
|
||||
joliet_level = 1;
|
||||
if (bcmp(sup->escape, "%/C", 3) == 0)
|
||||
joliet_level = 2;
|
||||
if (bcmp(sup->escape, "%/E", 3) == 0)
|
||||
joliet_level = 3;
|
||||
|
||||
if ((isonum_711 (sup->flags) & 1) &&
|
||||
!vfs_flagopt(mp->mnt_optnew, "brokenjoliet", NULL, 0))
|
||||
joliet_level = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ISO_VD_END:
|
||||
goto vd_end;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (bp) {
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
}
|
||||
vd_end:
|
||||
if (bp) {
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
|
||||
if (pri == NULL) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
logical_block_size =
|
||||
isonum_723 (high_sierra?
|
||||
pri_sierra->logical_block_size:
|
||||
pri->logical_block_size);
|
||||
|
||||
if (logical_block_size < DEV_BSIZE || logical_block_size > MAXBSIZE
|
||||
|| (logical_block_size & (logical_block_size - 1)) != 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rootp = (struct iso_directory_record *)
|
||||
(high_sierra?
|
||||
pri_sierra->root_directory_record:
|
||||
pri->root_directory_record);
|
||||
|
||||
isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK | M_ZERO);
|
||||
isomp->im_cp = cp;
|
||||
isomp->im_bo = bo;
|
||||
isomp->logical_block_size = logical_block_size;
|
||||
isomp->volume_space_size =
|
||||
isonum_733 (high_sierra?
|
||||
pri_sierra->volume_space_size:
|
||||
pri->volume_space_size);
|
||||
isomp->joliet_level = 0;
|
||||
/*
|
||||
* Since an ISO9660 multi-session CD can also access previous
|
||||
* sessions, we have to include them into the space consider-
|
||||
* ations. This doesn't yield a very accurate number since
|
||||
* parts of the old sessions might be inaccessible now, but we
|
||||
* can't do much better. This is also important for the NFS
|
||||
* filehandle validation.
|
||||
*/
|
||||
isomp->volume_space_size += ssector;
|
||||
bcopy (rootp, isomp->root, sizeof isomp->root);
|
||||
isomp->root_extent = isonum_733 (rootp->extent);
|
||||
isomp->root_size = isonum_733 (rootp->size);
|
||||
|
||||
isomp->im_bmask = logical_block_size - 1;
|
||||
isomp->im_bshift = ffs(logical_block_size) - 1;
|
||||
|
||||
pribp->b_flags |= B_AGE;
|
||||
brelse(pribp);
|
||||
pribp = NULL;
|
||||
|
||||
mp->mnt_data = (qaddr_t)isomp;
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
isomp->im_mountp = mp;
|
||||
isomp->im_dev = dev;
|
||||
isomp->im_devvp = devvp;
|
||||
|
||||
vfs_flagopt(mp->mnt_optnew, "norrip", &isomp->im_flags, ISOFSMNT_NORRIP);
|
||||
vfs_flagopt(mp->mnt_optnew, "gens", &isomp->im_flags, ISOFSMNT_GENS);
|
||||
vfs_flagopt(mp->mnt_optnew, "extatt", &isomp->im_flags, ISOFSMNT_EXTATT);
|
||||
vfs_flagopt(mp->mnt_optnew, "nojoliet", &isomp->im_flags, ISOFSMNT_NOJOLIET);
|
||||
vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV);
|
||||
|
||||
/* Check the Rock Ridge Extension support */
|
||||
if (!(isomp->im_flags & ISOFSMNT_NORRIP)) {
|
||||
if ((error = bread(isomp->im_devvp,
|
||||
(isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
|
||||
(isomp->im_bshift - DEV_BSHIFT),
|
||||
isomp->logical_block_size, NOCRED, &bp)) != 0)
|
||||
goto out;
|
||||
|
||||
rootp = (struct iso_directory_record *)bp->b_data;
|
||||
|
||||
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
|
||||
isomp->im_flags |= ISOFSMNT_NORRIP;
|
||||
} else {
|
||||
isomp->im_flags &= ~ISOFSMNT_GENS;
|
||||
}
|
||||
|
||||
/*
|
||||
* The contents are valid,
|
||||
* but they will get reread as part of another vnode, so...
|
||||
*/
|
||||
bp->b_flags |= B_AGE;
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error);
|
||||
if (error)
|
||||
goto out;
|
||||
cs_disk = vfs_getopts(mp->mnt_optnew, "cs_disk", &error);
|
||||
if (error)
|
||||
goto out;
|
||||
cd9660_iconv->open(cs_local, cs_disk, &isomp->im_d2l);
|
||||
cd9660_iconv->open(cs_disk, cs_local, &isomp->im_l2d);
|
||||
} else {
|
||||
isomp->im_d2l = NULL;
|
||||
isomp->im_l2d = NULL;
|
||||
}
|
||||
|
||||
if (high_sierra) {
|
||||
/* this effectively ignores all the mount flags */
|
||||
if (bootverbose)
|
||||
log(LOG_INFO, "cd9660: High Sierra Format\n");
|
||||
isomp->iso_ftype = ISO_FTYPE_HIGH_SIERRA;
|
||||
} else
|
||||
switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) {
|
||||
default:
|
||||
isomp->iso_ftype = ISO_FTYPE_DEFAULT;
|
||||
break;
|
||||
case ISOFSMNT_GENS|ISOFSMNT_NORRIP:
|
||||
isomp->iso_ftype = ISO_FTYPE_9660;
|
||||
break;
|
||||
case 0:
|
||||
if (bootverbose)
|
||||
log(LOG_INFO, "cd9660: RockRidge Extension\n");
|
||||
isomp->iso_ftype = ISO_FTYPE_RRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Decide whether to use the Joliet descriptor */
|
||||
|
||||
if (isomp->iso_ftype != ISO_FTYPE_RRIP && joliet_level) {
|
||||
if (bootverbose)
|
||||
log(LOG_INFO, "cd9660: Joliet Extension (Level %d)\n",
|
||||
joliet_level);
|
||||
rootp = (struct iso_directory_record *)
|
||||
sup->root_directory_record;
|
||||
bcopy (rootp, isomp->root, sizeof isomp->root);
|
||||
isomp->root_extent = isonum_733 (rootp->extent);
|
||||
isomp->root_size = isonum_733 (rootp->size);
|
||||
isomp->joliet_level = joliet_level;
|
||||
supbp->b_flags |= B_AGE;
|
||||
}
|
||||
|
||||
if (supbp) {
|
||||
brelse(supbp);
|
||||
supbp = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
if (pribp)
|
||||
brelse(pribp);
|
||||
if (supbp)
|
||||
brelse(supbp);
|
||||
if (cp != NULL) {
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
g_vfs_close(cp, td);
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
}
|
||||
if (isomp) {
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* unmount system call
|
||||
*/
|
||||
static int
|
||||
cd9660_unmount(mp, mntflags, td)
|
||||
struct mount *mp;
|
||||
int mntflags;
|
||||
struct thread *td;
|
||||
{
|
||||
struct iso_mnt *isomp;
|
||||
int error, flags = 0;
|
||||
|
||||
if (mntflags & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
#if 0
|
||||
mntflushbuf(mp, 0);
|
||||
if (mntinvalbuf(mp))
|
||||
return EBUSY;
|
||||
#endif
|
||||
if ((error = vflush(mp, 0, flags, td)))
|
||||
return (error);
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
|
||||
if (isomp->im_d2l)
|
||||
cd9660_iconv->close(isomp->im_d2l);
|
||||
if (isomp->im_l2d)
|
||||
cd9660_iconv->close(isomp->im_l2d);
|
||||
}
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
g_vfs_close(isomp->im_cp, td);
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
vrele(isomp->im_devvp);
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return root of a filesystem
|
||||
*/
|
||||
static int
|
||||
cd9660_root(mp, flags, vpp, td)
|
||||
struct mount *mp;
|
||||
int flags;
|
||||
struct vnode **vpp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct iso_mnt *imp = VFSTOISOFS(mp);
|
||||
struct iso_directory_record *dp =
|
||||
(struct iso_directory_record *)imp->root;
|
||||
ino_t ino = isodirino(dp, imp);
|
||||
|
||||
/*
|
||||
* With RRIP we must use the `.' entry of the root directory.
|
||||
* Simply tell vget, that it's a relocated directory.
|
||||
*/
|
||||
return (cd9660_vget_internal(mp, ino, LK_EXCLUSIVE, vpp,
|
||||
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get filesystem statistics.
|
||||
*/
|
||||
static int
|
||||
cd9660_statfs(mp, sbp, td)
|
||||
struct mount *mp;
|
||||
struct statfs *sbp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct iso_mnt *isomp;
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
sbp->f_bsize = isomp->logical_block_size;
|
||||
sbp->f_iosize = sbp->f_bsize; /* XXX */
|
||||
sbp->f_blocks = isomp->volume_space_size;
|
||||
sbp->f_bfree = 0; /* total free blocks */
|
||||
sbp->f_bavail = 0; /* blocks free for non superuser */
|
||||
sbp->f_files = 0; /* total files */
|
||||
sbp->f_ffree = 0; /* free file nodes */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* File handle to vnode
|
||||
*
|
||||
* Have to be really careful about stale file handles:
|
||||
* - check that the inode number is in range
|
||||
* - call iget() to get the locked inode
|
||||
* - check for an unallocated inode (i_mode == 0)
|
||||
* - check that the generation number matches
|
||||
*/
|
||||
|
||||
struct ifid {
|
||||
u_short ifid_len;
|
||||
u_short ifid_pad;
|
||||
int ifid_ino;
|
||||
long ifid_start;
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cd9660_fhtovp(mp, fhp, vpp)
|
||||
struct mount *mp;
|
||||
struct fid *fhp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct ifid *ifhp = (struct ifid *)fhp;
|
||||
struct iso_node *ip;
|
||||
struct vnode *nvp;
|
||||
int error;
|
||||
|
||||
#ifdef ISOFS_DBG
|
||||
printf("fhtovp: ino %d, start %ld\n",
|
||||
ifhp->ifid_ino, ifhp->ifid_start);
|
||||
#endif
|
||||
|
||||
if ((error = VFS_VGET(mp, ifhp->ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(nvp);
|
||||
if (ip->inode.iso_mode == 0) {
|
||||
vput(nvp);
|
||||
*vpp = NULLVP;
|
||||
return (ESTALE);
|
||||
}
|
||||
*vpp = nvp;
|
||||
vnode_create_vobject(*vpp, ip->i_size, curthread);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_vget(mp, ino, flags, vpp)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
int flags;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
|
||||
/*
|
||||
* XXXX
|
||||
* It would be nice if we didn't always set the `relocated' flag
|
||||
* and force the extra read, but I don't want to think about fixing
|
||||
* that right now.
|
||||
*/
|
||||
return (cd9660_vget_internal(mp, ino, flags, vpp,
|
||||
#if 0
|
||||
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
(struct iso_directory_record *)0));
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
int flags;
|
||||
struct vnode **vpp;
|
||||
int relocated;
|
||||
struct iso_directory_record *isodir;
|
||||
{
|
||||
struct iso_mnt *imp;
|
||||
struct iso_node *ip;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
struct cdev *dev;
|
||||
int error;
|
||||
|
||||
error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
|
||||
if (error || *vpp != NULL)
|
||||
return (error);
|
||||
|
||||
imp = VFSTOISOFS(mp);
|
||||
dev = imp->im_dev;
|
||||
|
||||
/* Allocate a new vnode/iso_node. */
|
||||
if ((error = getnewvnode("isofs", mp, &cd9660_vnodeops, &vp)) != 0) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE,
|
||||
M_WAITOK | M_ZERO);
|
||||
vp->v_data = ip;
|
||||
ip->i_vnode = vp;
|
||||
ip->i_number = ino;
|
||||
|
||||
error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL);
|
||||
if (error || *vpp != NULL)
|
||||
return (error);
|
||||
|
||||
if (isodir == 0) {
|
||||
int lbn, off;
|
||||
|
||||
lbn = lblkno(imp, ino);
|
||||
if (lbn >= imp->volume_space_size) {
|
||||
vput(vp);
|
||||
printf("fhtovp: lbn exceed volume space %d\n", lbn);
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
off = blkoff(imp, ino);
|
||||
if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
|
||||
vput(vp);
|
||||
printf("fhtovp: crosses block boundary %d\n",
|
||||
off + ISO_DIRECTORY_RECORD_SIZE);
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
error = bread(imp->im_devvp,
|
||||
lbn << (imp->im_bshift - DEV_BSHIFT),
|
||||
imp->logical_block_size, NOCRED, &bp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
brelse(bp);
|
||||
printf("fhtovp: bread error %d\n",error);
|
||||
return (error);
|
||||
}
|
||||
isodir = (struct iso_directory_record *)(bp->b_data + off);
|
||||
|
||||
if (off + isonum_711(isodir->length) >
|
||||
imp->logical_block_size) {
|
||||
vput(vp);
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
|
||||
off +isonum_711(isodir->length), off,
|
||||
isonum_711(isodir->length));
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (isonum_733(isodir->extent) +
|
||||
isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
printf("fhtovp: file start miss %d vs %d\n",
|
||||
isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length),
|
||||
ifhp->ifid_start);
|
||||
return (ESTALE);
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
bp = 0;
|
||||
|
||||
ip->i_mnt = imp;
|
||||
VREF(imp->im_devvp);
|
||||
|
||||
if (relocated) {
|
||||
/*
|
||||
* On relocated directories we must
|
||||
* read the `.' entry out of a dir.
|
||||
*/
|
||||
ip->iso_start = ino >> imp->im_bshift;
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
if ((error = cd9660_blkatoff(vp, (off_t)0, NULL, &bp)) != 0) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
isodir = (struct iso_directory_record *)bp->b_data;
|
||||
}
|
||||
|
||||
ip->iso_extent = isonum_733(isodir->extent);
|
||||
ip->i_size = isonum_733(isodir->size);
|
||||
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
|
||||
|
||||
/*
|
||||
* Setup time stamp, attribute
|
||||
*/
|
||||
vp->v_type = VNON;
|
||||
switch (imp->iso_ftype) {
|
||||
default: /* ISO_FTYPE_9660 */
|
||||
{
|
||||
struct buf *bp2;
|
||||
int off;
|
||||
if ((imp->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length)))
|
||||
cd9660_blkatoff(vp, (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
else
|
||||
bp2 = NULL;
|
||||
cd9660_defattr(isodir, ip, bp2, ISO_FTYPE_9660);
|
||||
cd9660_deftstamp(isodir, ip, bp2, ISO_FTYPE_9660);
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
break;
|
||||
}
|
||||
case ISO_FTYPE_RRIP:
|
||||
cd9660_rrip_analyze(isodir, ip, imp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* Initialize the associated vnode
|
||||
*/
|
||||
switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) {
|
||||
case VFIFO:
|
||||
vp->v_op = &cd9660_fifoops;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ip->iso_extent == imp->root_extent)
|
||||
vp->v_vflag |= VV_ROOT;
|
||||
|
||||
/*
|
||||
* XXX need generation number?
|
||||
*/
|
||||
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode pointer to File handle
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cd9660_vptofh(vp, fhp)
|
||||
struct vnode *vp;
|
||||
struct fid *fhp;
|
||||
{
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
struct ifid *ifhp;
|
||||
|
||||
ifhp = (struct ifid *)fhp;
|
||||
ifhp->ifid_len = sizeof(struct ifid);
|
||||
|
||||
ifhp->ifid_ino = ip->i_number;
|
||||
ifhp->ifid_start = ip->iso_start;
|
||||
|
||||
#ifdef ISOFS_DBG
|
||||
printf("vptofh: ino %d, start %ld\n",
|
||||
ifhp->ifid_ino,ifhp->ifid_start);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -1,833 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <fs/fifofs/fifo.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/filio.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vnode_pager.h>
|
||||
#include <vm/uma.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
|
||||
static vop_setattr_t cd9660_setattr;
|
||||
static vop_open_t cd9660_open;
|
||||
static vop_access_t cd9660_access;
|
||||
static vop_getattr_t cd9660_getattr;
|
||||
static vop_ioctl_t cd9660_ioctl;
|
||||
static vop_pathconf_t cd9660_pathconf;
|
||||
static vop_read_t cd9660_read;
|
||||
struct isoreaddir;
|
||||
static int iso_uiodir(struct isoreaddir *idp, struct dirent *dp, off_t off);
|
||||
static int iso_shipdir(struct isoreaddir *idp);
|
||||
static vop_readdir_t cd9660_readdir;
|
||||
static vop_readlink_t cd9660_readlink;
|
||||
static vop_strategy_t cd9660_strategy;
|
||||
|
||||
/*
|
||||
* Setattr call. Only allowed for block and character special devices.
|
||||
*/
|
||||
static int
|
||||
cd9660_setattr(ap)
|
||||
struct vop_setattr_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
struct vnode *a_vp;
|
||||
struct vattr *a_vap;
|
||||
struct ucred *a_cred;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vattr *vap = ap->a_vap;
|
||||
|
||||
if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
|
||||
vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
|
||||
vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)
|
||||
return (EROFS);
|
||||
if (vap->va_size != (u_quad_t)VNOVAL) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
return (EISDIR);
|
||||
case VLNK:
|
||||
case VREG:
|
||||
return (EROFS);
|
||||
case VCHR:
|
||||
case VBLK:
|
||||
case VSOCK:
|
||||
case VFIFO:
|
||||
case VNON:
|
||||
case VBAD:
|
||||
case VMARKER:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
|
||||
* The mode is shifted to select the owner/group/other fields. The
|
||||
* super user is granted all permissions.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cd9660_access(ap)
|
||||
struct vop_access_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_mode;
|
||||
struct ucred *a_cred;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
mode_t mode = ap->a_mode;
|
||||
|
||||
if (vp->v_type == VCHR || vp->v_type == VBLK)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
/*
|
||||
* Disallow write attempts unless the file is a socket,
|
||||
* fifo, or a block or character device resident on the
|
||||
* filesystem.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
return (EROFS);
|
||||
/* NOT REACHED */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (vaccess(vp->v_type, ip->inode.iso_mode, ip->inode.iso_uid,
|
||||
ip->inode.iso_gid, ap->a_mode, ap->a_cred, NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_open(ap)
|
||||
struct vop_open_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_mode;
|
||||
struct ucred *a_cred;
|
||||
struct thread *a_td;
|
||||
int a_fdidx;
|
||||
} */ *ap;
|
||||
{
|
||||
struct iso_node *ip = VTOI(ap->a_vp);
|
||||
|
||||
vnode_create_vobject(ap->a_vp, ip->i_size, ap->a_td);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cd9660_getattr(ap)
|
||||
struct vop_getattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct vattr *a_vap;
|
||||
struct ucred *a_cred;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
|
||||
vap->va_fsid = dev2udev(ip->i_mnt->im_dev);
|
||||
vap->va_fileid = ip->i_number;
|
||||
|
||||
vap->va_mode = ip->inode.iso_mode;
|
||||
vap->va_nlink = ip->inode.iso_links;
|
||||
vap->va_uid = ip->inode.iso_uid;
|
||||
vap->va_gid = ip->inode.iso_gid;
|
||||
vap->va_atime = ip->inode.iso_atime;
|
||||
vap->va_mtime = ip->inode.iso_mtime;
|
||||
vap->va_ctime = ip->inode.iso_ctime;
|
||||
vap->va_rdev = ip->inode.iso_rdev;
|
||||
|
||||
vap->va_size = (u_quad_t) ip->i_size;
|
||||
if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
|
||||
struct vop_readlink_args rdlnk;
|
||||
struct iovec aiov;
|
||||
struct uio auio;
|
||||
char *cp;
|
||||
|
||||
MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
aiov.iov_base = cp;
|
||||
aiov.iov_len = MAXPATHLEN;
|
||||
auio.uio_iov = &aiov;
|
||||
auio.uio_iovcnt = 1;
|
||||
auio.uio_offset = 0;
|
||||
auio.uio_rw = UIO_READ;
|
||||
auio.uio_segflg = UIO_SYSSPACE;
|
||||
auio.uio_td = ap->a_td;
|
||||
auio.uio_resid = MAXPATHLEN;
|
||||
rdlnk.a_uio = &auio;
|
||||
rdlnk.a_vp = ap->a_vp;
|
||||
rdlnk.a_cred = ap->a_cred;
|
||||
if (cd9660_readlink(&rdlnk) == 0)
|
||||
vap->va_size = MAXPATHLEN - auio.uio_resid;
|
||||
FREE(cp, M_TEMP);
|
||||
}
|
||||
vap->va_flags = 0;
|
||||
vap->va_gen = 1;
|
||||
vap->va_blocksize = ip->i_mnt->logical_block_size;
|
||||
vap->va_bytes = (u_quad_t) ip->i_size;
|
||||
vap->va_type = vp->v_type;
|
||||
vap->va_filerev = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for ioctl.
|
||||
*/
|
||||
static int
|
||||
cd9660_ioctl(ap)
|
||||
struct vop_ioctl_args /* {
|
||||
struct vnode *a_vp;
|
||||
u_long a_command;
|
||||
caddr_t a_data;
|
||||
int a_fflag;
|
||||
struct ucred *a_cred;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
|
||||
if (vp->v_type == VCHR || vp->v_type == VBLK)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
switch (ap->a_command) {
|
||||
|
||||
case FIOGETLBA:
|
||||
*(int *)(ap->a_data) = ip->iso_start;
|
||||
return 0;
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for reading.
|
||||
*/
|
||||
static int
|
||||
cd9660_read(ap)
|
||||
struct vop_read_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct iso_node *ip = VTOI(vp);
|
||||
struct iso_mnt *imp;
|
||||
struct buf *bp;
|
||||
daddr_t lbn, rablock;
|
||||
off_t diff;
|
||||
int rasize, error = 0;
|
||||
int seqcount;
|
||||
long size, n, on;
|
||||
|
||||
if (vp->v_type == VCHR || vp->v_type == VBLK)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
seqcount = ap->a_ioflag >> IO_SEQSHIFT;
|
||||
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
ip->i_flag |= IN_ACCESS;
|
||||
imp = ip->i_mnt;
|
||||
do {
|
||||
lbn = lblkno(imp, uio->uio_offset);
|
||||
on = blkoff(imp, uio->uio_offset);
|
||||
n = min((u_int)(imp->logical_block_size - on),
|
||||
uio->uio_resid);
|
||||
diff = (off_t)ip->i_size - uio->uio_offset;
|
||||
if (diff <= 0)
|
||||
return (0);
|
||||
if (diff < n)
|
||||
n = diff;
|
||||
size = blksize(imp, ip, lbn);
|
||||
rablock = lbn + 1;
|
||||
if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
|
||||
if (lblktosize(imp, rablock) < ip->i_size)
|
||||
error = cluster_read(vp, (off_t)ip->i_size,
|
||||
lbn, size, NOCRED, uio->uio_resid,
|
||||
(ap->a_ioflag >> 16), &bp);
|
||||
else
|
||||
error = bread(vp, lbn, size, NOCRED, &bp);
|
||||
} else {
|
||||
if (seqcount > 1 &&
|
||||
lblktosize(imp, rablock) < ip->i_size) {
|
||||
rasize = blksize(imp, ip, rablock);
|
||||
error = breadn(vp, lbn, size, &rablock,
|
||||
&rasize, 1, NOCRED, &bp);
|
||||
} else
|
||||
error = bread(vp, lbn, size, NOCRED, &bp);
|
||||
}
|
||||
n = min(n, size - bp->b_resid);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = uiomove(bp->b_data + on, (int)n, uio);
|
||||
brelse(bp);
|
||||
} while (error == 0 && uio->uio_resid > 0 && n != 0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure for reading directories
|
||||
*/
|
||||
struct isoreaddir {
|
||||
struct dirent saveent;
|
||||
struct dirent assocent;
|
||||
struct dirent current;
|
||||
off_t saveoff;
|
||||
off_t assocoff;
|
||||
off_t curroff;
|
||||
struct uio *uio;
|
||||
off_t uio_off;
|
||||
int eofflag;
|
||||
u_long *cookies;
|
||||
int ncookies;
|
||||
};
|
||||
|
||||
static int
|
||||
iso_uiodir(idp,dp,off)
|
||||
struct isoreaddir *idp;
|
||||
struct dirent *dp;
|
||||
off_t off;
|
||||
{
|
||||
int error;
|
||||
|
||||
dp->d_name[dp->d_namlen] = 0;
|
||||
dp->d_reclen = GENERIC_DIRSIZ(dp);
|
||||
|
||||
if (idp->uio->uio_resid < dp->d_reclen) {
|
||||
idp->eofflag = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (idp->cookies) {
|
||||
if (idp->ncookies <= 0) {
|
||||
idp->eofflag = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*idp->cookies++ = off;
|
||||
--idp->ncookies;
|
||||
}
|
||||
|
||||
if ((error = uiomove(dp, dp->d_reclen, idp->uio)) != 0)
|
||||
return (error);
|
||||
idp->uio_off = off;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iso_shipdir(idp)
|
||||
struct isoreaddir *idp;
|
||||
{
|
||||
struct dirent *dp;
|
||||
int cl, sl, assoc;
|
||||
int error;
|
||||
char *cname, *sname;
|
||||
|
||||
cl = idp->current.d_namlen;
|
||||
cname = idp->current.d_name;
|
||||
assoc = (cl > 1) && (*cname == ASSOCCHAR);
|
||||
if (assoc) {
|
||||
cl--;
|
||||
cname++;
|
||||
}
|
||||
|
||||
dp = &idp->saveent;
|
||||
sname = dp->d_name;
|
||||
if (!(sl = dp->d_namlen)) {
|
||||
dp = &idp->assocent;
|
||||
sname = dp->d_name + 1;
|
||||
sl = dp->d_namlen - 1;
|
||||
}
|
||||
if (sl > 0) {
|
||||
if (sl != cl
|
||||
|| bcmp(sname,cname,sl)) {
|
||||
if (idp->assocent.d_namlen) {
|
||||
if ((error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) != 0)
|
||||
return (error);
|
||||
idp->assocent.d_namlen = 0;
|
||||
}
|
||||
if (idp->saveent.d_namlen) {
|
||||
if ((error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) != 0)
|
||||
return (error);
|
||||
idp->saveent.d_namlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
idp->current.d_reclen = GENERIC_DIRSIZ(&idp->current);
|
||||
if (assoc) {
|
||||
idp->assocoff = idp->curroff;
|
||||
bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
|
||||
} else {
|
||||
idp->saveoff = idp->curroff;
|
||||
bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for readdir
|
||||
*/
|
||||
static int
|
||||
cd9660_readdir(ap)
|
||||
struct vop_readdir_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
int *a_eofflag;
|
||||
int *a_ncookies;
|
||||
u_long **a_cookies;
|
||||
} */ *ap;
|
||||
{
|
||||
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;
|
||||
int ncookies = 0;
|
||||
u_long *cookies = NULL;
|
||||
|
||||
dp = VTOI(vdp);
|
||||
imp = dp->i_mnt;
|
||||
bmask = imp->im_bmask;
|
||||
|
||||
MALLOC(idp, struct isoreaddir *, 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 {
|
||||
/*
|
||||
* Guess the number of cookies needed.
|
||||
*/
|
||||
ncookies = uio->uio_resid / 16;
|
||||
MALLOC(cookies, u_long *, ncookies * sizeof(u_long),
|
||||
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);
|
||||
if ((error =
|
||||
cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp)) != 0)
|
||||
break;
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
/*
|
||||
* Get pointer to next entry.
|
||||
*/
|
||||
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 || ISO_FTYPE_HIGH_SIERRA*/
|
||||
strcpy(idp->current.d_name,"..");
|
||||
if (idp->current.d_namlen == 1 && ep->name[0] == 0) {
|
||||
idp->current.d_namlen = 1;
|
||||
error = iso_uiodir(idp,&idp->current,idp->curroff);
|
||||
} else if (idp->current.d_namlen == 1 && ep->name[0] == 1) {
|
||||
idp->current.d_namlen = 2;
|
||||
error = iso_uiodir(idp,&idp->current,idp->curroff);
|
||||
} else {
|
||||
isofntrans(ep->name,idp->current.d_namlen,
|
||||
idp->current.d_name, &namelen,
|
||||
imp->iso_ftype == ISO_FTYPE_9660,
|
||||
isonum_711(ep->flags)&4,
|
||||
imp->joliet_level,
|
||||
imp->im_flags,
|
||||
imp->im_d2l);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
uio->uio_offset = idp->uio_off;
|
||||
*ap->a_eofflag = idp->eofflag;
|
||||
|
||||
FREE(idp, M_TEMP);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return target name of a symbolic link
|
||||
* Shouldn't we get the parent vnode and read the data from there?
|
||||
* This could eventually result in deadlocks in cd9660_lookup.
|
||||
* But otherwise the block read here is in the block buffer two times.
|
||||
*/
|
||||
typedef struct iso_directory_record ISODIR;
|
||||
typedef struct iso_node ISONODE;
|
||||
typedef struct iso_mnt ISOMNT;
|
||||
static int
|
||||
cd9660_readlink(ap)
|
||||
struct vop_readlink_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
ISONODE *ip;
|
||||
ISODIR *dirp;
|
||||
ISOMNT *imp;
|
||||
struct buf *bp;
|
||||
struct uio *uio;
|
||||
u_short symlen;
|
||||
int error;
|
||||
char *symname;
|
||||
|
||||
ip = VTOI(ap->a_vp);
|
||||
imp = ip->i_mnt;
|
||||
uio = ap->a_uio;
|
||||
|
||||
if (imp->iso_ftype != ISO_FTYPE_RRIP)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Get parents directory record block that this inode included.
|
||||
*/
|
||||
error = bread(imp->im_devvp,
|
||||
(ip->i_number >> imp->im_bshift) <<
|
||||
(imp->im_bshift - DEV_BSHIFT),
|
||||
imp->logical_block_size, NOCRED, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the directory pointer for this inode
|
||||
*/
|
||||
dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
|
||||
|
||||
/*
|
||||
* Just make sure, we have a right one....
|
||||
* 1: Check not cross boundary on block
|
||||
*/
|
||||
if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
|
||||
> (unsigned)imp->logical_block_size) {
|
||||
brelse(bp);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now get a buffer
|
||||
* Abuse a namei buffer for now.
|
||||
*/
|
||||
if (uio->uio_segflg == UIO_SYSSPACE)
|
||||
symname = uio->uio_iov->iov_base;
|
||||
else
|
||||
symname = uma_zalloc(namei_zone, M_WAITOK);
|
||||
|
||||
/*
|
||||
* Ok, we just gathering a symbolic name in SL record.
|
||||
*/
|
||||
if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
|
||||
if (uio->uio_segflg != UIO_SYSSPACE)
|
||||
uma_zfree(namei_zone, symname);
|
||||
brelse(bp);
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* Don't forget before you leave from home ;-)
|
||||
*/
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* return with the symbolic name to caller's.
|
||||
*/
|
||||
if (uio->uio_segflg != UIO_SYSSPACE) {
|
||||
error = uiomove(symname, symlen, uio);
|
||||
uma_zfree(namei_zone, symname);
|
||||
return (error);
|
||||
}
|
||||
uio->uio_resid -= symlen;
|
||||
uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + symlen;
|
||||
uio->uio_iov->iov_len -= symlen;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the logical to physical mapping if not done already,
|
||||
* then call the device strategy routine.
|
||||
*/
|
||||
static int
|
||||
cd9660_strategy(ap)
|
||||
struct vop_strategy_args /* {
|
||||
struct buf *a_vp;
|
||||
struct buf *a_bp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct buf *bp = ap->a_bp;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct iso_node *ip;
|
||||
struct bufobj *bo;
|
||||
|
||||
ip = VTOI(vp);
|
||||
if (vp->v_type == VBLK || vp->v_type == VCHR)
|
||||
panic("cd9660_strategy: spec");
|
||||
if (bp->b_blkno == bp->b_lblkno) {
|
||||
bp->b_blkno = (ip->iso_start + bp->b_lblkno) <<
|
||||
(ip->i_mnt->im_bshift - DEV_BSHIFT);
|
||||
if ((long)bp->b_blkno == -1) /* XXX: cut&paste junk ? */
|
||||
clrbuf(bp);
|
||||
}
|
||||
if ((long)bp->b_blkno == -1) { /* XXX: cut&paste junk ? */
|
||||
bufdone(bp);
|
||||
return (0);
|
||||
}
|
||||
bp->b_iooffset = dbtob(bp->b_blkno);
|
||||
bo = ip->i_mnt->im_bo;
|
||||
BO_STRATEGY(bo, bp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return POSIX pathconf information applicable to cd9660 filesystems.
|
||||
*/
|
||||
static int
|
||||
cd9660_pathconf(ap)
|
||||
struct vop_pathconf_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_name;
|
||||
register_t *a_retval;
|
||||
} */ *ap;
|
||||
{
|
||||
|
||||
switch (ap->a_name) {
|
||||
case _PC_LINK_MAX:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
case _PC_NAME_MAX:
|
||||
if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
|
||||
*ap->a_retval = NAME_MAX;
|
||||
else
|
||||
*ap->a_retval = 37;
|
||||
return (0);
|
||||
case _PC_PATH_MAX:
|
||||
*ap->a_retval = PATH_MAX;
|
||||
return (0);
|
||||
case _PC_PIPE_BUF:
|
||||
*ap->a_retval = PIPE_BUF;
|
||||
return (0);
|
||||
case _PC_CHOWN_RESTRICTED:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
case _PC_NO_TRUNC:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Global vfs data structures for cd9660
|
||||
*/
|
||||
struct vop_vector cd9660_vnodeops = {
|
||||
.vop_default = &default_vnodeops,
|
||||
.vop_open = cd9660_open,
|
||||
.vop_access = cd9660_access,
|
||||
.vop_bmap = cd9660_bmap,
|
||||
.vop_cachedlookup = cd9660_lookup,
|
||||
.vop_getattr = cd9660_getattr,
|
||||
.vop_inactive = cd9660_inactive,
|
||||
.vop_ioctl = cd9660_ioctl,
|
||||
.vop_lookup = vfs_cache_lookup,
|
||||
.vop_pathconf = cd9660_pathconf,
|
||||
.vop_read = cd9660_read,
|
||||
.vop_readdir = cd9660_readdir,
|
||||
.vop_readlink = cd9660_readlink,
|
||||
.vop_reclaim = cd9660_reclaim,
|
||||
.vop_setattr = cd9660_setattr,
|
||||
.vop_strategy = cd9660_strategy,
|
||||
};
|
||||
|
||||
/*
|
||||
* Special device vnode ops
|
||||
*/
|
||||
|
||||
struct vop_vector cd9660_fifoops = {
|
||||
.vop_default = &fifo_specops,
|
||||
.vop_access = cd9660_access,
|
||||
.vop_getattr = cd9660_getattr,
|
||||
.vop_inactive = cd9660_inactive,
|
||||
.vop_reclaim = cd9660_reclaim,
|
||||
.vop_setattr = cd9660_setattr,
|
||||
};
|
@ -1,343 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)iso.h 8.6 (Berkeley) 5/10/95
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
struct iso_volume_descriptor {
|
||||
char type[ISODCL(1,1)]; /* 711 */
|
||||
char id[ISODCL(2,6)];
|
||||
char version[ISODCL(7,7)];
|
||||
char unused[ISODCL(8,8)];
|
||||
char type_sierra[ISODCL(9,9)]; /* 711 */
|
||||
char id_sierra[ISODCL(10,14)];
|
||||
char version_sierra[ISODCL(15,15)];
|
||||
char data[ISODCL(16,2048)];
|
||||
};
|
||||
|
||||
/* volume descriptor types */
|
||||
#define ISO_VD_PRIMARY 1
|
||||
#define ISO_VD_SUPPLEMENTARY 2
|
||||
#define ISO_VD_END 255
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
#define ISO_ECMA_ID "CDW01"
|
||||
|
||||
#define ISO_SIERRA_ID "CDROM"
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char unused1 [ISODCL ( 8, 8)];
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char unused3 [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
#define ISO_DEFAULT_BLOCK_SIZE 2048
|
||||
|
||||
/*
|
||||
* Used by Microsoft Joliet extension to ISO9660. Almost the same
|
||||
* as PVD, but byte position 8 is a flag, and 89-120 is for escape.
|
||||
*/
|
||||
|
||||
struct iso_supplementary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char flags [ISODCL ( 8, 8)]; /* 711? */
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char escape [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
struct iso_sierra_primary_descriptor {
|
||||
char unknown1 [ISODCL ( 1, 8)]; /* 733 */
|
||||
char type [ISODCL ( 9, 9)]; /* 711 */
|
||||
char id [ISODCL ( 10, 14)];
|
||||
char version [ISODCL ( 15, 15)]; /* 711 */
|
||||
char unused1 [ISODCL ( 16, 16)];
|
||||
char system_id [ISODCL ( 17, 48)]; /* achars */
|
||||
char volume_id [ISODCL ( 49, 80)]; /* dchars */
|
||||
char unused2 [ISODCL ( 81, 88)];
|
||||
char volume_space_size [ISODCL ( 89, 96)]; /* 733 */
|
||||
char unused3 [ISODCL ( 97, 128)];
|
||||
char volume_set_size [ISODCL (129, 132)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (133, 136)]; /* 723 */
|
||||
char logical_block_size [ISODCL (137, 140)]; /* 723 */
|
||||
char path_table_size [ISODCL (141, 148)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (149, 152)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (153, 156)]; /* 731 */
|
||||
char unknown2 [ISODCL (157, 160)]; /* 731 */
|
||||
char unknown3 [ISODCL (161, 164)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (165, 168)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (169, 172)]; /* 732 */
|
||||
char unknown4 [ISODCL (173, 176)]; /* 732 */
|
||||
char unknown5 [ISODCL (177, 180)]; /* 732 */
|
||||
char root_directory_record [ISODCL (181, 214)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (215, 342)]; /* dchars */
|
||||
char publisher_id [ISODCL (343, 470)]; /* achars */
|
||||
char preparer_id [ISODCL (471, 598)]; /* achars */
|
||||
char application_id [ISODCL (599, 726)]; /* achars */
|
||||
char copyright_id [ISODCL (727, 790)]; /* achars */
|
||||
char creation_date [ISODCL (791, 806)]; /* ? */
|
||||
char modification_date [ISODCL (807, 822)]; /* ? */
|
||||
char expiration_date [ISODCL (823, 838)]; /* ? */
|
||||
char effective_date [ISODCL (839, 854)]; /* ? */
|
||||
char file_structure_version [ISODCL (855, 855)]; /* 711 */
|
||||
char unused4 [ISODCL (856, 2048)];
|
||||
};
|
||||
|
||||
struct iso_directory_record {
|
||||
char length [ISODCL (1, 1)]; /* 711 */
|
||||
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
u_char extent [ISODCL (3, 10)]; /* 733 */
|
||||
u_char size [ISODCL (11, 18)]; /* 733 */
|
||||
char date [ISODCL (19, 25)]; /* 7 by 711 */
|
||||
char flags [ISODCL (26, 26)];
|
||||
char file_unit_size [ISODCL (27, 27)]; /* 711 */
|
||||
char interleave [ISODCL (28, 28)]; /* 711 */
|
||||
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
|
||||
char name_len [ISODCL (33, 33)]; /* 711 */
|
||||
char name [1]; /* XXX */
|
||||
};
|
||||
/* can't take sizeof(iso_directory_record), because of possible alignment
|
||||
of the last entry (34 instead of 33) */
|
||||
#define ISO_DIRECTORY_RECORD_SIZE 33
|
||||
|
||||
struct iso_extended_attributes {
|
||||
u_char owner [ISODCL (1, 4)]; /* 723 */
|
||||
u_char group [ISODCL (5, 8)]; /* 723 */
|
||||
u_char perm [ISODCL (9, 10)]; /* 9.5.3 */
|
||||
char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
|
||||
char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
|
||||
char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
|
||||
char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
|
||||
char recfmt [ISODCL (79, 79)]; /* 711 */
|
||||
char recattr [ISODCL (80, 80)]; /* 711 */
|
||||
u_char reclen [ISODCL (81, 84)]; /* 723 */
|
||||
char system_id [ISODCL (85, 116)]; /* achars */
|
||||
char system_use [ISODCL (117, 180)];
|
||||
char version [ISODCL (181, 181)]; /* 711 */
|
||||
char len_esc [ISODCL (182, 182)]; /* 711 */
|
||||
char reserved [ISODCL (183, 246)];
|
||||
u_char len_au [ISODCL (247, 250)]; /* 723 */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/* CD-ROM Format type */
|
||||
enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP,
|
||||
ISO_FTYPE_JOLIET, ISO_FTYPE_ECMA, ISO_FTYPE_HIGH_SIERRA };
|
||||
|
||||
#ifndef ISOFSMNT_ROOT
|
||||
#define ISOFSMNT_ROOT 0
|
||||
#endif
|
||||
|
||||
struct iso_mnt {
|
||||
int im_flags;
|
||||
|
||||
struct mount *im_mountp;
|
||||
struct cdev *im_dev;
|
||||
struct vnode *im_devvp;
|
||||
|
||||
struct g_consumer *im_cp;
|
||||
struct bufobj *im_bo;
|
||||
|
||||
int logical_block_size;
|
||||
int im_bshift;
|
||||
int im_bmask;
|
||||
|
||||
int volume_space_size;
|
||||
|
||||
char root[ISODCL (157, 190)];
|
||||
int root_extent;
|
||||
int root_size;
|
||||
enum ISO_FTYPE iso_ftype;
|
||||
|
||||
int rr_skip;
|
||||
int rr_skip0;
|
||||
|
||||
int joliet_level;
|
||||
|
||||
void *im_d2l;
|
||||
void *im_l2d;
|
||||
};
|
||||
|
||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||
|
||||
#define blkoff(imp, loc) ((loc) & (imp)->im_bmask)
|
||||
#define lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
|
||||
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
|
||||
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
|
||||
|
||||
int cd9660_vget_internal(struct mount *, ino_t, int, struct vnode **, int,
|
||||
struct iso_directory_record *);
|
||||
#define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
|
||||
size_t, struct proc *))eopnotsupp)
|
||||
|
||||
extern struct vop_vector cd9660_vnodeops;
|
||||
extern struct vop_vector cd9660_fifoops;
|
||||
|
||||
int isochar(u_char *, u_char *, int, u_short *, int *, int, void *);
|
||||
int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *);
|
||||
void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *);
|
||||
ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
|
||||
u_short sgetrune(const char *, size_t, char const **, int, void *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* The isonum_xxx functions are inlined anyway, and could come handy even
|
||||
* outside the kernel. Thus we don't hide them here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 7xy
|
||||
* x -> 1 = 8 bits, 2 = 16 bits, 3 = 32 bits
|
||||
* y -> 1 = little-endian, 2 = big-endian, 3 = both (le then be)
|
||||
*/
|
||||
|
||||
static __inline uint8_t
|
||||
isonum_711(unsigned char *p)
|
||||
{
|
||||
return p[0];
|
||||
}
|
||||
|
||||
static __inline uint8_t
|
||||
isonum_712(unsigned char *p)
|
||||
{
|
||||
return p[0];
|
||||
}
|
||||
|
||||
static __inline uint8_t
|
||||
isonum_713(unsigned char *p)
|
||||
{
|
||||
return p[0];
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
isonum_721(unsigned char *p)
|
||||
{
|
||||
return (p[0] | p[1] << 8);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
isonum_722(unsigned char *p)
|
||||
{
|
||||
return (p[1] | p[0] << 8);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
isonum_723(unsigned char *p)
|
||||
{
|
||||
return (p[0] | p[1] << 8);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
isonum_731(unsigned char *p)
|
||||
{
|
||||
return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
isonum_732(unsigned char *p)
|
||||
{
|
||||
return (p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
isonum_733(unsigned char *p)
|
||||
{
|
||||
return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
|
||||
}
|
||||
|
||||
/*
|
||||
* Associated files have a leading '='.
|
||||
*/
|
||||
#define ASSOCCHAR '='
|
@ -1,82 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)iso_rrip.h 8.2 (Berkeley) 1/23/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Analyze function flag (similar to RR field bits)
|
||||
*/
|
||||
#define ISO_SUSP_ATTR 0x0001
|
||||
#define ISO_SUSP_DEVICE 0x0002
|
||||
#define ISO_SUSP_SLINK 0x0004
|
||||
#define ISO_SUSP_ALTNAME 0x0008
|
||||
#define ISO_SUSP_CLINK 0x0010
|
||||
#define ISO_SUSP_PLINK 0x0020
|
||||
#define ISO_SUSP_RELDIR 0x0040
|
||||
#define ISO_SUSP_TSTAMP 0x0080
|
||||
#define ISO_SUSP_IDFLAG 0x0100
|
||||
#define ISO_SUSP_EXTREF 0x0200
|
||||
#define ISO_SUSP_CONT 0x0400
|
||||
#define ISO_SUSP_OFFSET 0x0800
|
||||
#define ISO_SUSP_STOP 0x1000
|
||||
#define ISO_SUSP_UNKNOWN 0x8000
|
||||
|
||||
typedef struct {
|
||||
struct iso_node *inop;
|
||||
int fields; /* interesting fields in this analysis */
|
||||
daddr_t iso_ce_blk; /* block of continuation area */
|
||||
off_t iso_ce_off; /* offset of continuation area */
|
||||
int iso_ce_len; /* length of continuation area */
|
||||
struct iso_mnt *imp; /* mount structure */
|
||||
ino_t *inump; /* inode number pointer */
|
||||
char *outbuf; /* name/symbolic link output area */
|
||||
u_short *outlen; /* length of above */
|
||||
u_short maxlen; /* maximum length of above */
|
||||
int cont; /* continuation of above */
|
||||
} ISO_RRIP_ANALYZE;
|
||||
|
||||
struct iso_directory_record;
|
||||
|
||||
int cd9660_rrip_analyze(struct iso_directory_record *isodir,
|
||||
struct iso_node *inop, struct iso_mnt *imp);
|
||||
int cd9660_rrip_getname(struct iso_directory_record *isodir,
|
||||
char *outbuf, u_short *outlen,
|
||||
ino_t *inump, struct iso_mnt *imp);
|
||||
int cd9660_rrip_getsymname(struct iso_directory_record *isodir,
|
||||
char *outbuf, u_short *outlen,
|
||||
struct iso_mnt *imp);
|
||||
int cd9660_rrip_offset(struct iso_directory_record *isodir,
|
||||
struct iso_mnt *imp);
|
Loading…
x
Reference in New Issue
Block a user