new byte-order-independent isofs patches from mw

This commit is contained in:
cgd 1993-09-03 04:37:52 +00:00
parent 90fe4cc799
commit fb0dffe28a
7 changed files with 226 additions and 80 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: iso.h,v 1.3 1993/07/19 13:40:01 cgd Exp $
* $Id: iso.h,v 1.4 1993/09/03 04:37:52 cgd Exp $
*/
#define ISODCL(from, to) (to - from + 1)
@ -67,6 +67,9 @@ struct iso_directory_record {
char name_len [ISODCL (33, 33)]; /* 711 */
char name [0];
};
/* 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
/* CD-ROM Fromat type */
enum ISO_FTYPE { ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
@ -111,3 +114,22 @@ int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
int isofs_vptofh __P((struct vnode *vp, struct fid *fhp));
int isofs_init __P(());
struct iso_node;
int iso_bmap __P((struct iso_node *ip, int lblkno, daddr_t *result));
int iso_blkatoff __P((struct iso_node *ip, off_t offset, char **res, struct buf **bpp));
int iso_iget __P((struct iso_node *xp, ino_t ino, struct iso_node **ipp,
struct iso_directory_record *isodir));
int iso_iput __P((struct iso_node *ip));
int iso_ilock __P((struct iso_node *ip));
int iso_iunlock __P((struct iso_node *ip));
int isonum_711 __P((unsigned char *p));
int isonum_712 __P((signed char *p));
int isonum_721 __P((unsigned char *p));
int isonum_722 __P((unsigned char *p));
int isonum_723 __P((unsigned char *p));
int isonum_731 __P((unsigned char *p));
int isonum_732 __P((unsigned char *p));
int isonum_733 __P((unsigned char *p));
int isofs_mountroot __P((void));
int iso_mountfs __P((struct vnode *devvp, struct mount *mp, struct proc *p));
int iso_mountedon __P((struct vnode *vp));

View File

@ -1,5 +1,5 @@
/*
* $Id: isofs_bmap.c,v 1.2 1993/05/20 03:30:44 cgd Exp $
* $Id: isofs_bmap.c,v 1.3 1993/09/03 04:37:53 cgd Exp $
*/
#include "param.h"
@ -15,7 +15,7 @@
iso_bmap(ip, lblkno, result)
struct iso_node *ip;
int lblkno;
int *result;
daddr_t *result;
{
*result = (ip->iso_extent + lblkno)
* (ip->i_mnt->im_bsize / DEV_BSIZE);

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
* $Id: isofs_lookup.c,v 1.5 1993/07/19 13:40:03 cgd Exp $
* $Id: isofs_lookup.c,v 1.6 1993/09/03 04:37:54 cgd Exp $
*/
#include "param.h"
@ -49,6 +49,12 @@
#include "iso_rrip.h"
#include "isofs_rrip.h"
#ifdef ISOFS_DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
struct nchstats nchstats;
/*
@ -112,7 +118,7 @@ isofs_lookup(vdp, ndp, p)
int error;
int reclen;
int namelen;
short namelen;
char altname[251];
int i;
@ -127,8 +133,10 @@ isofs_lookup(vdp, ndp, p)
/*
* Check accessiblity of directory.
*/
if ((dp->iso_flags & 2) == 0)
if ((dp->iso_flags & 2) == 0) {
DPRINTF(("isofs_lookup: iso_flags = %x, ENOTDIR\n", dp->iso_flags));
return (ENOTDIR);
}
/*
* We now have a segment name to search for, and a directory to search.
@ -235,6 +243,7 @@ searchloop:
(bp->b_un.b_addr + entryoffsetinblock);
reclen = isonum_711 (ep->length);
DPRINTF(("isofs_lookup: reclen = %d\n", reclen));
if (reclen == 0) {
/* skip to next block, if any */
ndp->ni_ufs.ufs_offset =
@ -243,22 +252,31 @@ searchloop:
continue;
}
if (reclen < sizeof (struct iso_directory_record))
if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
DPRINTF(("isofs_lookup: reclen too small (<%d)\n",
ISO_DIRECTORY_RECORD_SIZE));
/* illegal entry, stop */
break;
}
/* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size)
if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) {
DPRINTF(("isofs_lookup: cross-block entry\n"));
/* entries are not allowed to cross boundaries */
break;
}
/*
* Check for a name match.
*/
namelen = isonum_711 (ep->name_len);
DPRINTF(("isofs_lookup: namelen = %d\n", namelen));
if (reclen < sizeof (struct iso_directory_record) + namelen)
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen) {
DPRINTF(("isofs_lookup: reclen < %d + %d\n",
ISO_DIRECTORY_RECORD_SIZE, namelen));
/* illegal entry, stop */
break;
}
if (namelen == 1
&& ((ndp->ni_namelen == 1
@ -275,7 +293,15 @@ searchloop:
goto found;
} else {
switch ( imp->iso_ftype ) {
default:
DPRINTF(("isofs_lookup: unsupported ftype = %x\n",
imp->iso_ftype));
/* default to iso-mode, any extension should support
iso, not ? */
/* FALLTHRU */
case ISO_FTYPE_9660:
DPRINTF(("isofs_lookup: ftype == ISO\n"));
if( ( namelen >= ndp->ni_namelen ) &&
( isofncmp( ndp->ni_ptr, ndp->ni_namelen, ep->name, namelen ) ) ) {
ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent);
@ -284,6 +310,7 @@ searchloop:
}
break;
case ISO_FTYPE_RRIP:
DPRINTF(("isofs_lookup: ftype == RRIP\n"));
isofs_rrip_getname( ep, altname, &namelen );
if ( ( namelen == ndp->ni_namelen ) &&
( !bcmp( ndp->ni_ptr, altname, ndp->ni_namelen ) ) ) {
@ -292,8 +319,6 @@ searchloop:
goto found;
}
break;
default:
break;
}
}
ndp->ni_ufs.ufs_offset += reclen;

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: isofs_rrip.c,v 1.1 1993/07/19 13:40:06 cgd Exp $
* $Id: isofs_rrip.c,v 1.2 1993/09/03 04:37:55 cgd Exp $
*/
#include "param.h"
@ -46,6 +46,14 @@
#include "isofs_rrip.h"
#include "iso_rrip.h"
#include "dirent.h"
#ifdef ISOFS_DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
/*
* POSIX file attribute
*/
@ -53,10 +61,10 @@ static int isofs_rrip_attr( p, ana )
ISO_RRIP_ATTR *p;
ISO_RRIP_ANALYZE *ana;
{
ana->inode.iso_mode = isonum_731(p->mode_l);
ana->inode.iso_uid = (uid_t)isonum_731(p->uid_l);
ana->inode.iso_gid = (gid_t)isonum_731(p->gid_l);
/* ana->inode.iso_links = isonum_731(p->links_l); */
ana->inode.iso_mode = isonum_733(p->mode_l);
ana->inode.iso_uid = (uid_t)isonum_733(p->uid_l);
ana->inode.iso_gid = (gid_t)isonum_733(p->gid_l);
/* ana->inode.iso_links = isonum_733(p->links_l); */
return;
}
@ -86,8 +94,8 @@ ISO_RRIP_ANALYZE *ana;
printf("isofs:%s[%d] high=0x%08x, low=0x%08x\n",
buf,
isonum_711(p->h.length),
isonum_731(p->dev_t_high_l),
isonum_731(p->dev_t_low_l)
isonum_733(p->dev_t_high_l),
isonum_733(p->dev_t_low_l)
);
#endif
return;
@ -394,7 +402,8 @@ static RRIP_TABLE rrip_table [] = {
{ 'R', 'R', isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG },
{ 'E', 'R', isofs_rrip_exflag, 0, ISO_SUSP_EXFLAG },
{ 'S', 'P', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN },
{ 'C', 'E', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN }
{ 'C', 'E', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN },
{ 'A', 'A', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN }
};
int isofs_rrip_analyze ( isodir, analyze )
@ -477,7 +486,7 @@ setdefault:
int isofs_rrip_getname( isodir, outbuf, outlen )
struct iso_directory_record *isodir;
char *outbuf;
int *outlen;
short *outlen;
{
ISO_SUSP_HEADER *phead, *pend;
ISO_RRIP_ALTNAME *p;
@ -498,6 +507,7 @@ int *outlen;
if ( pend != phead ) {
while ( pend >= phead + 1) {
if ( bcmp( phead->type, "NM", 2 ) == 0 ) {
DPRINTF(("isofs_rrip_getname: found NM record\n"));
found = 1;
break;
}
@ -507,8 +517,14 @@ int *outlen;
if ( found == 1 ) {
p = (ISO_RRIP_ALTNAME *)phead;
*outlen = isonum_711( p->h.length ) - sizeof( ISO_RRIP_ALTNAME );
DPRINTF(("isofs_rrip_getname: len = %d, rlen = %d, name = %*.*s\n",
isonum_711(p->h.length), *outlen,
*outlen, *outlen, &p->flags + 1));
bcopy( (char *)( &p->flags + 1 ), outbuf, *outlen );
outbuf[*outlen] = 0;
} else {
DPRINTF(("no rrip, name = %s (%08x%08x)\n",
isodir->name, *(long *)isodir->name, *(long *)(isodir->name+4)));
isofntrans(isodir->name, isonum_711(isodir->name_len), outbuf, outlen );
if ( *outlen == 1) {
switch ( outbuf[0] ) {
@ -534,7 +550,7 @@ int isofs_rrip_getsymname( vp, isodir, outbuf, outlen )
struct vnode *vp;
struct iso_directory_record *isodir;
char *outbuf;
int *outlen;
short *outlen;
{
register ISO_RRIP_SLINK_COMPONENT *pcomp;
register ISO_SUSP_HEADER *phead, *pend;

View File

@ -1,88 +1,116 @@
/*
* $Id: isofs_util.c,v 1.3 1993/07/19 13:40:08 cgd Exp $
* $Id: isofs_util.c,v 1.4 1993/09/03 04:37:56 cgd Exp $
*/
#include "param.h"
#include "systm.h"
#include "namei.h"
#include "resourcevar.h"
#include "kernel.h"
#include "file.h"
#include "stat.h"
#include "buf.h"
#include "proc.h"
#include "conf.h"
#include "mount.h"
#include "vnode.h"
#include "specdev.h"
#include "fifo.h"
#include "malloc.h"
#include "dir.h"
#include "iso.h"
#include "dirent.h"
#include "machine/endian.h"
int
isonum_711 (p)
char *p;
unsigned char *p;
{
return (*p & 0xff);
return (*p);
}
int
isonum_712 (p)
char *p;
signed char *p;
{
int val;
val = *p;
if (val & 0x80)
val |= 0xffffff00;
return (val);
return (*p);
}
int
isonum_721 (p)
char *p;
unsigned char *p;
{
return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
/* little endian short */
#if BYTE_ORDER != LITTLE_ENDIAN
printf ("isonum_721 called on non little-endian machine!\n");
#endif
return *(short *)p;
}
int
isonum_722 (p)
char *p;
unsigned char *p;
{
return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
/* big endian short */
#if BYTE_ORDER != BIG_ENDIAN
printf ("isonum_722 called on non big-endian machine!\n");
#endif
return *(short *)p;
}
int
isonum_723 (p)
char *p;
unsigned char *p;
{
#if 0
if (p[0] != p[3] || p[1] != p[2]) {
fprintf (stderr, "invalid format 7.2.3 number\n");
exit (1);
}
#if BYTE_ORDER == BIG_ENDIAN
return isonum_722 (p + 2);
#elif BYTE_ORDER == LITTLE_ENDIAN
return isonum_721 (p);
#else
printf ("isonum_723 unsupported byte order!\n");
return 0;
#endif
return (isonum_721 (p));
}
int
isonum_731 (p)
unsigned char *p;
{
return ((p[0] & 0xff)
| ((p[1] & 0xff) << 8)
| ((p[2] & 0xff) << 16)
| ((p[3] & 0xff) << 24));
/* little endian long */
#if BYTE_ORDER != LITTLE_ENDIAN
printf ("isonum_731 called on non little-endian machine!\n");
#endif
return *(long *)p;
}
int
isonum_732 (p)
unsigned char *p;
{
return (((p[0] & 0xff) << 24)
| ((p[1] & 0xff) << 16)
| ((p[2] & 0xff) << 8)
| (p[3] & 0xff));
/* big endian long */
#if BYTE_ORDER != BIG_ENDIAN
printf ("isonum_732 called on non big-endian machine!\n");
#endif
return *(long *)p;
}
int
isonum_733 (p)
unsigned char *p;
{
int i;
#if 0
for (i = 0; i < 4; i++) {
if (p[i] != p[7-i]) {
fprintf (stderr, "bad format 7.3.3 number\n");
exit (1);
}
}
#if BYTE_ORDER == BIG_ENDIAN
return isonum_732 (p + 4);
#elif BYTE_ORDER == LITTLE_ENDIAN
return isonum_731 (p);
#else
printf ("isonum_733 unsupported byte order!\n");
return 0;
#endif
return (isonum_731 (p));
}
/*

View File

@ -1,5 +1,5 @@
/*
* $Id: isofs_vfsops.c,v 1.5 1993/07/19 13:40:09 cgd Exp $
* $Id: isofs_vfsops.c,v 1.6 1993/09/03 04:37:57 cgd Exp $
*/
#include "param.h"
@ -21,6 +21,12 @@
#include "iso.h"
#include "isofs_node.h"
#ifdef ISOFS_DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
extern int enodev ();
struct vfsops isofs_vfsops = {
@ -145,8 +151,10 @@ isofs_mount(mp, path, data, ndp, p)
ndp->ni_nameiop = LOOKUP | FOLLOW;
ndp->ni_segflg = UIO_USERSPACE;
ndp->ni_dirp = args.fspec;
if (error = namei(ndp, p))
if (error = namei(ndp, p)) {
DPRINTF(("isofs: can't lookup mountpoint\n"));
return (error);
}
devvp = ndp->ni_vp;
if (devvp->v_type != VBLK) {
vrele(devvp);
@ -157,12 +165,15 @@ isofs_mount(mp, path, data, ndp, p)
return (ENXIO);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
error = iso_mountfs(devvp, mp, p);
else {
if (devvp != imp->im_devvp)
if (error)
DPRINTF(("isofs: iso_mountfs = %d\n", error));
} else {
if (devvp != imp->im_devvp) {
DPRINTF(("isofs: devvp != imp->im_devvp"));
error = EINVAL; /* needs translation */
else
} else
vrele(devvp);
}
if (error) {
@ -181,11 +192,13 @@ isofs_mount(mp, path, data, ndp, p)
}
(void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size);
DPRINTF(("isofs: imp->im_fsmnt = %s, size = %d\n", imp->im_fsmnt, size));
bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size);
bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
MNAMELEN);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
DPRINTF(("isofs: mntfromname = %s, size = %d\n", mp->mnt_stat.f_mntfromname, size));
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) isofs_statfs(mp, &mp->mnt_stat, p);
return (0);
@ -225,13 +238,17 @@ iso_mountfs(devvp, mp, p)
* (except for root, which might share swap device for miniroot).
* Flush out any old buffers remaining from a previous use.
*/
if (error = iso_mountedon(devvp))
if (error = iso_mountedon(devvp)) {
DPRINTF(("iso_mountfs: iso_mountedon = %d\n", error));
return (error);
}
if (vcount(devvp) > 1 && devvp != rootvp)
return (EBUSY);
vinvalbuf(devvp, 1);
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p)) {
DPRINTF(("iso_mountfs: VOP_OPEN = %d\n", error));
return (error);
}
needclose = 1;
/* This is the "logical sector size". The standard says this
@ -247,11 +264,15 @@ iso_mountfs(devvp, mp, p)
vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
DPRINTF(("isofs: vpd->id == %x != ISO_STANDARD_ID(%x)\n",
vdp->id, ISO_STANDARD_ID));
error = EINVAL;
goto out;
}
if (isonum_711 (vdp->type) == ISO_VD_END) {
DPRINTF(("isofs: vpd->type == %x == ISO_VD_END(%x)\n",
isonum_711 (vdp->type), ISO_VD_END));
error = EINVAL;
goto out;
}
@ -262,6 +283,8 @@ iso_mountfs(devvp, mp, p)
}
if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
DPRINTF(("isofs: vdp->type == %x != ISO_VD_PRIMARY(%x)\n",
isonum_711 (vdp->type), ISO_VD_PRIMARY));
error = EINVAL;
goto out;
}
@ -273,6 +296,7 @@ iso_mountfs(devvp, mp, p)
if (logical_block_size < DEV_BSIZE
|| logical_block_size >= MAXBSIZE
|| (logical_block_size & (logical_block_size - 1)) != 0) {
DPRINTF(("isofs: logical_block_size = %d\n", logical_block_size));
error = EINVAL;
goto out;
}
@ -508,8 +532,7 @@ isofs_fhtovp(mp, fhp, vpp)
if (ifhp->ifid_lbn >= imp->volume_space_size)
return (EINVAL);
if (ifhp->ifid_offset + sizeof (struct iso_directory_record)
>= imp->im_bsize)
if (ifhp->ifid_offset + ISO_DIRECTORY_RECORD_SIZE >= imp->im_bsize)
return (EINVAL);
if (error = bread (imp->im_devvp,

View File

@ -1,5 +1,5 @@
/*
* $Id: isofs_vnops.c,v 1.6 1993/08/02 23:00:04 mycroft Exp $
* $Id: isofs_vnops.c,v 1.7 1993/09/03 04:37:58 cgd Exp $
*/
#include "param.h"
#include "systm.h"
@ -22,6 +22,12 @@
#include "isofs_node.h"
#include "iso_rrip.h"
#ifdef ISOFS_DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
/*
* Open called.
*
@ -250,14 +256,18 @@ isofs_readdir(vp, uio, cred, eofflagp)
iso_offset = uio->uio_offset;
entryoffsetinblock = iso_blkoff(imp, iso_offset);
DPRINTF(("isofs_readdir: iso_offset = %d, entryoff..=%d\n",
iso_offset, entryoffsetinblock));
if (entryoffsetinblock != 0) {
if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp))
return (error);
}
endsearch = ip->i_size;
DPRINTF(("isofs_readdir: endsearch = %d\n", endsearch));
while (iso_offset < endsearch && uio->uio_resid > 0) {
DPRINTF(("isooff=%d, entryoff=%d\n", iso_offset, entryoffsetinblock));
/*
* If offset is on a block boundary,
* read the next directory block.
@ -271,6 +281,7 @@ isofs_readdir(vp, uio, cred, eofflagp)
(char **)0, &bp))
return (error);
entryoffsetinblock = 0;
DPRINTF(("new block at iso_offset = %d\n", iso_offset));
}
/*
* Get pointer to next entry.
@ -280,28 +291,36 @@ isofs_readdir(vp, uio, cred, eofflagp)
(bp->b_un.b_addr + entryoffsetinblock);
reclen = isonum_711 (ep->length);
DPRINTF(("isofs_readdir: reclen = %d\n", reclen));
if (reclen == 0) {
/* skip to next block, if any */
iso_offset = roundup (iso_offset,
imp->logical_block_size);
DPRINTF(("isofs: skip to next block, if any\n"));
continue;
}
if (reclen < sizeof (struct iso_directory_record))
if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
DPRINTF(("isofs_readdir: reclen too small!\n"));
error = EINVAL;
/* illegal entry, stop */
break;
}
/* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size)
if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) {
DPRINTF(("isofs_readdir: entryoffsetinblock + reclen - 1 > lbs\n"));
error = EINVAL;
/* illegal directory, so stop looking */
break;
}
dirent.d_fileno = isonum_733 (ep->extent);
dirent.d_namlen = isonum_711 (ep->name_len);
if (reclen < sizeof (struct iso_directory_record)
+ dirent.d_namlen)
if (reclen < ISO_DIRECTORY_RECORD_SIZE + dirent.d_namlen) {
error = EINVAL;
/* illegal entry, stop */
break;
}
/*
*
@ -318,13 +337,20 @@ isofs_readdir(vp, uio, cred, eofflagp)
break;
default:
switch ( imp->iso_ftype ) {
case ISO_FTYPE_RRIP:
isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen );
break;
default:
DPRINTF(("isofs_readdir: unknown ftype %x\n",
imp->iso_ftype));
/* default to iso */
/* FALLTHRU */
case ISO_FTYPE_9660:
DPRINTF(("isofs_readdir: 9660\n"));
isofntrans(ep->name, dirent.d_namlen, dirent.d_name, &dirent.d_namlen);
break;
default:
case ISO_FTYPE_RRIP:
DPRINTF(("isofs_readdir: RRIP\n"));
isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen );
break;
}
break;
@ -333,6 +359,11 @@ isofs_readdir(vp, uio, cred, eofflagp)
dirent.d_name[dirent.d_namlen] = 0;
dirent.d_reclen = DIRSIZ (&dirent);
DPRINTF(("d_fileno = %d, d_namlen = %d, name = %s (0x%08x%08x)\n",
dirent.d_fileno, dirent.d_namlen, dirent.d_name,
*(unsigned long*)dirent.d_name,
*(unsigned long*)(dirent.d_name+4)));
if (uio->uio_resid < dirent.d_reclen)
break;
@ -343,6 +374,7 @@ isofs_readdir(vp, uio, cred, eofflagp)
entryoffsetinblock += reclen;
}
DPRINTF(("isofs_readdir: out of directory scan loop\n"));
if (bp)
brelse (bp);