aboutsummaryrefslogtreecommitdiff
path: root/CLEAR-1.1.5.1-PATCHES/patch013
diff options
context:
space:
mode:
Diffstat (limited to 'CLEAR-1.1.5.1-PATCHES/patch013')
-rw-r--r--CLEAR-1.1.5.1-PATCHES/patch0136088
1 files changed, 6088 insertions, 0 deletions
diff --git a/CLEAR-1.1.5.1-PATCHES/patch013 b/CLEAR-1.1.5.1-PATCHES/patch013
new file mode 100644
index 000000000000..953dcb4265ea
--- /dev/null
+++ b/CLEAR-1.1.5.1-PATCHES/patch013
@@ -0,0 +1,6088 @@
+From julian Wed Aug 24 18:55:24 1994
+Return-Path: <julian>
+Received: by tfs.com (smail3.1.28.1)
+Message-Id: <m0qdU2E-0003wQC@TFS.COM>
+Date: Wed, 24 Aug 94 18:55 PDT
+From: julian (Julian Elischer)
+To: phk
+Subject: patch por rockridge
+Status: RO
+
+
+> From dfr@render.com Mon Aug 22 12:36:15 PDT 1994
+> Article: 2309 of comp.os.386bsd.bugs
+> Path: tfs.com!agate!howland.reston.ans.net!cs.utexas.edu!uunet!news.sprintlink.net!demon!minnow.render.com!minnow.render.com!dfr
+> From: dfr@render.com (Doug Rabson)
+> Newsgroups: comp.os.386bsd.bugs
+> Subject: RockRidge fixes for FreeBSD-1.1.5 (long)
+> Date: 22 Aug 1994 12:31:25 GMT
+> Organization: RenderMorphics Ltd.
+> Lines: 6062
+> Message-ID: <DFR.94Aug22133125@minnow.render.com>
+> NNTP-Posting-Host: minnow.render.com
+>
+> I have had a couple of requests for this. These patches are based on
+> a patch set which I had for FreeBSD-1.1 which contained a port of
+> NetBSD's isofs to FreeBSD.
+>
+> I have minimally tested it and it appears to work for my only
+> RockRidge CD (X11R6) and several ordinary CDs. There appears to be a
+> problem in exporting CDs over NFS. Some long directories get
+> truncated.
+Poul, the problem refered to is apparently not fixable under the present
+1.1.5.1 vfs system (so he says)
+so I think this should be added as well
+
+------------------------------cut here------------------------------
+diff -cr sbin/mount_isofs/Makefile src/sbin/mount_isofs/Makefile
+*** sbin/mount_isofs/Makefile Wed Jul 21 22:57:33 1993
+--- src/sbin/mount_isofs/Makefile Mon Aug 15 15:17:59 1994
+***************
+*** 1,4 ****
+! # patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+
+ PROG = mount_isofs
+ MAN8 = mount_isofs.8
+--- 1,4 ----
+! # patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+
+ PROG = mount_isofs
+ MAN8 = mount_isofs.8
+diff -cr sbin/mount_isofs/mount_isofs.8 src/sbin/mount_isofs/mount_isofs.8
+*** sbin/mount_isofs/mount_isofs.8 Mon Feb 7 02:47:56 1994
+--- src/sbin/mount_isofs/mount_isofs.8 Mon Aug 15 15:17:59 1994
+***************
+*** 14,20 ****
+ .\" must display the following acknowledgement:
+ .\" This product includes software developed by Christopher G. Demetriou.
+ .\" 3. The name of the author may not be used to endorse or promote products
+! .\" derived from this software withough specific prior written permission
+ .\"
+ .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+--- 14,20 ----
+ .\" must display the following acknowledgement:
+ .\" This product includes software developed by Christopher G. Demetriou.
+ .\" 3. The name of the author may not be used to endorse or promote products
+! .\" derived from this software without specific prior written permission
+ .\"
+ .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+***************
+*** 27,37 ****
+ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ .\"
+! .\" patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ .\"
+ .Dd July 19, 1993
+ .Dt MOUNT_ISOFS 8
+! .Os
+ .Sh NAME
+ .Nm mount_isofs
+ .Nd mount an ISO-9660 filesystem
+--- 27,37 ----
+ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ .\"
+! .\" patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ .\"
+ .Dd July 19, 1993
+ .Dt MOUNT_ISOFS 8
+! .Os NetBSD 0.9
+ .Sh NAME
+ .Nm mount_isofs
+ .Nd mount an ISO-9660 filesystem
+***************
+*** 39,44 ****
+--- 39,46 ----
+ .Nm mount_isofs
+ .Op Fl F Ar fsoptions
+ .Op Fl norrip
++ .Op Fl gen
++ .Op Fl extattr
+ .Pa special
+ .Pa node
+ .Sh DESCRIPTION
+***************
+*** 51,57 ****
+ indicated by
+ .Pa node .
+ This command is normally executed by
+! .Xr mount 8 .
+ at boot time.
+ .Pp
+ If the filesystem includes Rockridge extensions, they are
+--- 53,59 ----
+ indicated by
+ .Pa node .
+ This command is normally executed by
+! .Xr mount 8
+ at boot time.
+ .Pp
+ If the filesystem includes Rockridge extensions, they are
+***************
+*** 60,71 ****
+ flag is used. If that option is given to
+ .Nm
+ then the Rockridge extensions will be ignored.
+ .Sh EXAMPLES
+ .Bd -literal -offset indent -compact
+! mount_isofs /dev/cd0a /cdrom
+! mount_isofs \-norrip /dev/cd0a /cdrom
+! mount \-t isofs /dev/cd0a /cdrom
+! mount \-t isofs \-o \-norrip /dev/cd0a /cdrom
+ .Ed
+ .Sh SEE ALSO
+ .Xr mount 2 ,
+--- 62,89 ----
+ flag is used. If that option is given to
+ .Nm
+ then the Rockridge extensions will be ignored.
++ .Pp
++ Version numbers on files are normally stripped on directory listings.
++ If you want to see those, use the
++ .Fl gen
++ flag.
++ Otherwise, if there are files with different version numbers on the disk,
++ only the last one will be listed.
++ In either case, you may open a file with or without explicitly stating the
++ version number.
++ .Pp
++ If a disk contains extended attributes, they are normally ignored.
++ You can enable the usage of extended attributes with the
++ .Fl extattr
++ flag.
+ .Sh EXAMPLES
+ .Bd -literal -offset indent -compact
+! mount_isofs /dev/cd0d /cdrom
+! mount_isofs \-norrip /dev/cd0d /cdrom
+! mount_isofs \-norrip \-gen /dev/cd0d /cdrom
+! mount \-t isofs /dev/cd0d /cdrom
+! mount \-t isofs \-o \-norrip /dev/cd0d /cdrom
+! mount \-t isofs \-o \-gen,\-extattr /dev/cd0d /cdrom
+ .Ed
+ .Sh SEE ALSO
+ .Xr mount 2 ,
+***************
+*** 76,82 ****
+ ("CDROM001") format;
+ it does not.
+ .Pp
+! POSIX device nodes are currently not supported.
+ .Pp
+ The filesystem name might need some rethinking, and some would
+ say it should run as a user process.
+--- 94,105 ----
+ ("CDROM001") format;
+ it does not.
+ .Pp
+! POSIX device node mapping is currently not supported.
+! .Pp
+! Version numbers are not stripped if Rockridge extensions are in use.
+! In this case, accessing files that don't have Rockridge names without
+! version numbers gets the one with the lowest version number and not
+! the one with the highest.
+ .Pp
+ The filesystem name might need some rethinking, and some would
+ say it should run as a user process.
+diff -cr sbin/mount_isofs/mount_isofs.c src/sbin/mount_isofs/mount_isofs.c
+*** sbin/mount_isofs/mount_isofs.c Sun Oct 24 04:30:08 1993
+--- src/sbin/mount_isofs/mount_isofs.c Mon Aug 15 16:02:41 1994
+***************
+*** 1,9 ****
+ #ifndef lint
+! static char rcsid[] = "/home/ncvs/src/CLEAR-1.1.5.1-PATCHES/patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp";
+! #endif
+
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/mount.h>
+
+ void
+--- 1,10 ----
+ #ifndef lint
+! static char rcsid[] = "patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp";
+! #endif /* not lint */
+
+ #include <stdio.h>
+ #include <sys/types.h>
++ #define ISOFS
+ #include <sys/mount.h>
+
+ void
+***************
+*** 20,40 ****
+ {
+ char *dev;
+ char *dir;
+! struct ufs_args args;
+ int c;
+! int opts;
+!
+! opts = MNT_RDONLY;
+
+ argc--;
+ argv++;
+ while (argc > 2) {
+ if (!strcmp("-F", argv[0])) {
+ argc--; argv++;
+! opts |= atoi(argv[0]);
+ argc--; argv++;
+ } else if (!strcmp(argv[0], "-norrip")) {
+! opts |= MNT_NORRIP;
+ argc--; argv++;
+ } else
+ usage();
+--- 21,45 ----
+ {
+ char *dev;
+ char *dir;
+! struct iso_args args;
+ int c;
+! int opts = 0, mntflags = 0;
+
+ argc--;
+ argv++;
+ while (argc > 2) {
+ if (!strcmp("-F", argv[0])) {
+ argc--; argv++;
+! mntflags |= atoi(argv[0]);
+ argc--; argv++;
+ } else if (!strcmp(argv[0], "-norrip")) {
+! opts |= ISOFSMNT_NORRIP;
+! argc--; argv++;
+! } else if (!strcmp(argv[0], "-gen")) {
+! opts |= ISOFSMNT_GENS;
+! argc--; argv++;
+! } else if (!strcmp(argv[0], "-extattr")) {
+! opts |= ISOFSMNT_EXTATT;
+ argc--; argv++;
+ } else
+ usage();
+***************
+*** 44,53 ****
+ dir = argv[1];
+
+ args.fspec = dev;
+! args.exflags = MNT_EXRDONLY;
+ args.exroot = 0;
+
+! if (mount (MOUNT_ISOFS, dir, opts, &args) < 0) {
+ perror ("mount");
+ exit (1);
+ }
+--- 49,58 ----
+ dir = argv[1];
+
+ args.fspec = dev;
+! args.flags = opts;
+ args.exroot = 0;
+
+! if (mount (MOUNT_ISOFS, dir, mntflags, &args) < 0) {
+ perror ("mount");
+ exit (1);
+ }
+diff -cr sys/isofs/TODO src/sys/isofs/TODO
+*** sys/isofs/TODO Tue Jul 20 04:27:21 1993
+--- src/sys/isofs/TODO Mon Aug 15 15:17:55 1994
+***************
+*** 1,4 ****
+! # patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+
+ 1) should understand "older", original High Sierra ("CDROM001") type
+
+--- 1,4 ----
+! # patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+
+ 1) should understand "older", original High Sierra ("CDROM001") type
+
+***************
+*** 13,34 ****
+ o File Attribute
+ o Time stamp
+ o uid, gid
+
+ Except follows:
+
+! o POSIX device modes
+
+! I have no idea right now, we should check a REAL implementation
+! for 386BSD.....
+
+- o Limitation of 8 level directory( ISO9660 limitation )
+-
+- Rock Ridge Extension are defined with the "CL/PL/RE" for getting
+- rid of this limitation. But as far as I test the cdroms,I'v never
+- seen this definition and we can access the over 8 level without
+- it. (Another word, this limitation is NOT physical ISO9660's
+- FORMAT limitation for unix stuffs.... I believe... )
+-
+ 3) should be called cdfs, as there are other ISO file system soon possible
+
+ Not yet. Probably we should make another file system when the ECMA draft
+--- 13,28 ----
+ 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
+
+ 3) should be called cdfs, as there are other ISO file system soon possible
+
+ Not yet. Probably we should make another file system when the ECMA draft
+***************
+*** 48,55 ****
+ 6) should run as a user process, and not take up kernel space (cdroms
+ are slow)
+
+! Not yet. And addition, we should try to avoid a long seek by a absolute path
+! with using the PATH TABLE or other method.
+
+ 7) ECMA support.
+
+--- 42,48 ----
+ 6) should run as a user process, and not take up kernel space (cdroms
+ are slow)
+
+! Not yet.
+
+ 7) ECMA support.
+
+***************
+*** 62,66 ****
+--- 55,77 ----
+ 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 )
+
++ 9) Access checks in isofs_access
++
++ Not yet.
++
++ 10) Support for generation numbers
++
++ Yes. Default is to list only the last file (the one with the highest
++ generation number). If you mount with -gen, all files are shown with
++ their generation numbers. In both cases you can specify the generation
++ number on opening files (if you happen to know it) or leave it off,
++ when it will again find the last file.
++
++ 11) Support for extended attributes
++
++ Yes. Since this requires an extra block buffer for the attributes
++ this must be enabled on mounting with the option -extattr.
++
+ ----------
+ Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp)
++ Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de)
+diff -cr sys/isofs/iso.h src/sys/isofs/iso.h
+*** sys/isofs/iso.h Sun Dec 19 00:51:02 1993
+--- src/sys/isofs/iso.h Mon Aug 15 15:17:55 1994
+***************
+*** 1,5 ****
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISO_H_
+--- 1,5 ----
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISO_H_
+***************
+*** 70,105 ****
+ char name_len [ISODCL (33, 33)]; /* 711 */
+ char name [0];
+ };
+
+! /* CD-ROM Fromat type */
+! enum ISO_FTYPE { ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
+
+ struct iso_mnt {
+ int logical_block_size;
+ int volume_space_size;
+ struct vnode *im_devvp;
+ char im_fsmnt[50];
+
+- int im_ronly;
+- int im_fmod;
+ struct mount *im_mountp;
+ dev_t im_dev;
+!
+ int im_bshift;
+ int im_bmask;
+! int im_bsize;
+!
+ char root[ISODCL (157, 190)];
+ int root_extent;
+ int root_size;
+ enum ISO_FTYPE iso_ftype;
+ };
+
+ #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
+
+! #define iso_blkoff(imp, loc) ((loc) & ~(imp)->im_bmask)
+ #define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
+! #define iso_blksize(imp, ip, lbn) ((imp)->im_bsize)
+ #define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
+
+
+--- 70,133 ----
+ 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
++
++ struct iso_extended_attributes {
++ unsigned char owner [ISODCL (1, 4)]; /* 723 */
++ unsigned char group [ISODCL (5, 8)]; /* 723 */
++ unsigned 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 */
++ unsigned 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)];
++ unsigned char len_au [ISODCL (247, 250)]; /* 723 */
++ };
++
++ /* CD-ROM Format type */
++ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
+
+! #ifndef ISOFSMNT_ROOT
+! #define ISOFSMNT_ROOT 0
+! #endif
+
+ struct iso_mnt {
++ int im_flags;
++
+ int logical_block_size;
+ int volume_space_size;
+ struct vnode *im_devvp;
+ char im_fsmnt[50];
+
+ struct mount *im_mountp;
+ dev_t im_dev;
+!
+ int im_bshift;
+ int im_bmask;
+!
+ char root[ISODCL (157, 190)];
+ int root_extent;
+ int root_size;
+ enum ISO_FTYPE iso_ftype;
++
++ int rr_skip;
++ int rr_skip0;
+ };
+
+ #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
+
+! #define iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask)
+ #define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
+! #define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size)
+ #define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
+
+
+***************
+*** 112,129 ****
+ int isofs_sync __P((struct mount *mp, int waitfor));
+ int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
+ int isofs_vptofh __P((struct vnode *vp, struct fid *fhp));
+! void isofs_init __P((void));
+
+! /* From isofs_util.c: */
+! extern int isonum_711(char *);
+! extern int isonum_712(char *);
+! extern int isonum_721(char *);
+! extern int isonum_722(char *);
+! extern int isonum_723(char *);
+! extern int isonum_731(u_char *);
+! extern int isonum_732(u_char *);
+! extern int isonum_733(u_char *);
+! extern int isofncmp(char *, int, char *, int);
+! extern void isofntrans(char *, int, char *, int *);
+
+ #endif /* _ISOFS_ISO_H_ */
+--- 140,222 ----
+ int isofs_sync __P((struct mount *mp, int waitfor));
+ int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
+ int isofs_vptofh __P((struct vnode *vp, struct fid *fhp));
+! void 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, struct buf **bpp));
+! int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated,
+! struct iso_node **ipp, struct iso_directory_record *isodir));
+! void iso_iput __P((struct iso_node *ip));
+! void iso_ilock __P((struct iso_node *ip));
+! void iso_iunlock __P((struct iso_node *ip));
+! int isofs_mountroot __P((void));
+!
+! extern inline int
+! isonum_711(p)
+! unsigned char *p;
+! {
+! return *p;
+! }
+!
+! extern inline int
+! isonum_712(p)
+! char *p;
+! {
+! return *p;
+! }
+!
+! extern inline int
+! isonum_721(p)
+! unsigned char *p;
+! {
+! return *p|((char)p[1] << 8);
+! }
+!
+! extern inline int
+! isonum_722(p)
+! unsigned char *p;
+! {
+! return ((char)*p << 8)|p[1];
+! }
+!
+! extern inline int
+! isonum_723(p)
+! unsigned char *p;
+! {
+! return isonum_721(p);
+! }
+!
+! extern inline int
+! isonum_731(p)
+! unsigned char *p;
+! {
+! return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
+! }
+!
+! extern inline int
+! isonum_732(p)
+! unsigned char *p;
+! {
+! return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
+! }
+!
+! extern inline int
+! isonum_733(p)
+! unsigned char *p;
+! {
+! return isonum_731(p);
+! }
+!
+! int isofncmp __P((unsigned char *fn, int fnlen,
+! unsigned char *isofn, int isolen));
+! void isofntrans __P((unsigned char *infn, int infnlen,
+! unsigned char *outfn, unsigned short *outfnlen,
+! int original, int assoc));
+!
+! /*
+! * Associated files have a leading '='.
+! */
+! #define ASSOCCHAR '='
+
+ #endif /* _ISOFS_ISO_H_ */
+diff -cr sys/isofs/iso_rrip.h /src/sys/isofs/iso_rrip.h
+*** sys/isofs/iso_rrip.h Sun Nov 7 17:46:03 1993
+--- src/sys/isofs/iso_rrip.h Mon Aug 15 15:17:55 1994
+***************
+*** 29,42 ****
+ * SUCH DAMAGE.
+ *
+ * from: @(#)iso_rrip.h
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISO_RRIP_H_
+ #define _ISOFS_ISO_RRIP_H_ 1
+
+ /*
+! * Analyze function flag
+ */
+ #define ISO_SUSP_ATTR 0x0001
+ #define ISO_SUSP_DEVICE 0x0002
+--- 29,42 ----
+ * SUCH DAMAGE.
+ *
+ * from: @(#)iso_rrip.h
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISO_RRIP_H_
+ #define _ISOFS_ISO_RRIP_H_ 1
+
+ /*
+! * Analyze function flag (similar to RR field bits)
+ */
+ #define ISO_SUSP_ATTR 0x0001
+ #define ISO_SUSP_DEVICE 0x0002
+***************
+*** 47,60 ****
+ #define ISO_SUSP_RELDIR 0x0040
+ #define ISO_SUSP_TSTAMP 0x0080
+ #define ISO_SUSP_IDFLAG 0x0100
+! #define ISO_SUSP_EXFLAG 0x0200
+! #define ISO_SUSP_UNKNOWN 0x0400
+
+ typedef struct {
+! ISO_RRIP_INODE inode;
+! u_short iso_altlen; /* Alt Name length */
+! u_short iso_symlen; /* Symbol Name length */
+! char *iso_altname; /* Alt Name (no Null terminated ) */
+! char *iso_symname; /* Symbol Name (no NULL termninated )*/
+ } ISO_RRIP_ANALYZE;
+ #endif /* _ISOFS_ISO_RRIP_H_ */
+--- 47,81 ----
+ #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;
++
++ int isofs_rrip_analyze __P((struct iso_directory_record *isodir,
++ struct iso_node *inop, struct iso_mnt *imp));
++ int isofs_rrip_getname __P((struct iso_directory_record *isodir,
++ char *outbuf, u_short *outlen,
++ ino_t *inump, struct iso_mnt *imp));
++ int isofs_rrip_getsymname __P((struct iso_directory_record *isodir,
++ char *outbuf, u_short *outlen,
++ struct iso_mnt *imp));
++ int isofs_rrip_offset __P((struct iso_directory_record *isodir,
++ struct iso_mnt *imp));
++
+ #endif /* _ISOFS_ISO_RRIP_H_ */
+diff -cr sys/isofs/isofs_bmap.c src/sys/isofs/isofs_bmap.c
+*** sys/isofs/isofs_bmap.c Sun Dec 19 00:51:03 1993
+--- src/sys/isofs/isofs_bmap.c Mon Aug 15 15:17:55 1994
+***************
+*** 1,25 ****
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+! #include "namei.h"
+! #include "buf.h"
+! #include "file.h"
+! #include "vnode.h"
+! #include "mount.h"
+
+! #include "iso.h"
+! #include "isofs_node.h"
+
+ int
+ iso_bmap(ip, lblkno, result)
+! struct iso_node *ip;
+! int lblkno;
+! int *result;
+ {
+! *result = (ip->iso_extent + lblkno)
+! * (ip->i_mnt->im_bsize / DEV_BSIZE);
+! return (0);
+ }
+--- 1,24 ----
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include <sys/param.h>
+! #include <sys/namei.h>
+! #include <sys/buf.h>
+! #include <sys/file.h>
+! #include <sys/vnode.h>
+! #include <sys/mount.h>
+
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+
+ int
+ iso_bmap(ip, lblkno, result)
+! struct iso_node *ip;
+! int lblkno;
+! daddr_t *result;
+ {
+! *result = (ip->iso_start + lblkno)
+! * (ip->i_mnt->logical_block_size / DEV_BSIZE);
+! return 0;
+ }
+diff -cr sys/isofs/isofs_lookup.c src/sys/isofs/isofs_lookup.c
+*** sys/isofs/isofs_lookup.c Thu Nov 25 01:32:22 1993
+--- src/sys/isofs/isofs_lookup.c Mon Aug 15 15:17:56 1994
+***************
+*** 34,56 ****
+ * SUCH DAMAGE.
+ *
+ * from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+! #include "namei.h"
+! #include "buf.h"
+! #include "file.h"
+! #include "vnode.h"
+! #include "mount.h"
+
+! #include "iso.h"
+! #include "isofs_node.h"
+! #include "iso_rrip.h"
+! #include "isofs_rrip.h"
+!
+! struct nchstats nchstats;
+
+ /*
+ * Convert a component of a pathname into a pointer to a locked inode.
+--- 34,56 ----
+ * SUCH DAMAGE.
+ *
+ * from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include <sys/param.h>
+! #include <sys/systm.h>
+! #include <sys/namei.h>
+! #include <sys/buf.h>
+! #include <sys/file.h>
+! #include <sys/vnode.h>
+! #include <sys/mount.h>
+!
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+! #include <isofs/iso_rrip.h>
+! #include <isofs/isofs_rrip.h>
+
+! struct nchstats iso_nchstats;
+
+ /*
+ * Convert a component of a pathname into a pointer to a locked inode.
+***************
+*** 96,123 ****
+ register struct iso_node *dp; /* the directory we are searching */
+ register struct iso_mnt *imp; /* file system that directory is in */
+ struct buf *bp = 0; /* a buffer of directory entries */
+! register struct iso_directory_record *ep;
+! /* the current directory entry */
+! int entryoffsetinblock = 0; /* offset of ep in bp's buffer */
+! enum {NONE, COMPACT, FOUND} slotstatus;
+! int slotoffset = -1; /* offset of area with free space */
+! int slotsize; /* size of area at slotoffset */
+! int slotfreespace; /* amount of space free in slot */
+! int slotneeded; /* size of the entry we're seeking */
+ int numdirpasses; /* strategy for directory search */
+! int endsearch; /* offset to end directory search */
+ struct iso_node *pdp; /* saved dp during symlink work */
+ struct iso_node *tdp; /* returned by iget */
+ int flag; /* LOOKUP, CREATE, RENAME, or DELETE */
+ int lockparent; /* 1 => lockparent flag is set */
+ int wantparent; /* 1 => wantparent or lockparent flag */
+ int error;
+!
+ int reclen;
+! int namelen;
+! char altname[251];
+! int i;
+!
+ ndp->ni_dvp = vdp;
+ ndp->ni_vp = NULL;
+ dp = VTOI(vdp);
+--- 96,120 ----
+ register struct iso_node *dp; /* the directory we are searching */
+ register struct iso_mnt *imp; /* file system that directory is in */
+ struct buf *bp = 0; /* a buffer of directory entries */
+! struct iso_directory_record *ep;/* the current directory entry */
+! off_t entryoffsetinblock = 0; /* offset of ep in bp's buffer */
+! off_t saveoffset = 0; /* offset of last directory entry in dir */
+ int numdirpasses; /* strategy for directory search */
+! off_t endsearch; /* offset to end directory search */
+ struct iso_node *pdp; /* saved dp during symlink work */
+ struct iso_node *tdp; /* returned by iget */
+ int flag; /* LOOKUP, CREATE, RENAME, or DELETE */
+ int lockparent; /* 1 => lockparent flag is set */
+ int wantparent; /* 1 => wantparent or lockparent flag */
+ int error;
+! ino_t ino = 0;
+ int reclen;
+! u_short namelen;
+! char altname[NAME_MAX];
+! int res;
+! int assoc, len;
+! char *name;
+!
+ ndp->ni_dvp = vdp;
+ ndp->ni_vp = NULL;
+ dp = VTOI(vdp);
+***************
+*** 125,137 ****
+ lockparent = ndp->ni_nameiop & LOCKPARENT;
+ flag = ndp->ni_nameiop & OPMASK;
+ wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
+!
+ /*
+ * Check accessiblity of directory.
+ */
+! if ((dp->iso_flags & 2) == 0)
+! return (ENOTDIR);
+!
+ /*
+ * We now have a segment name to search for, and a directory to search.
+ *
+--- 122,136 ----
+ lockparent = ndp->ni_nameiop & LOCKPARENT;
+ flag = ndp->ni_nameiop & OPMASK;
+ wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
+!
+ /*
+ * Check accessiblity of directory.
+ */
+! if (vdp->v_type != VDIR)
+! return ENOTDIR;
+! if (error = isofs_access(vdp, VEXEC, ndp->ni_cred, p))
+! return error;
+!
+ /*
+ * We now have a segment name to search for, and a directory to search.
+ *
+***************
+*** 141,150 ****
+ */
+ if (error = cache_lookup(ndp)) {
+ int vpid; /* capability number of vnode */
+!
+ if (error == ENOENT)
+ return (error);
+! #ifdef PARANOID
+ if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot)
+ panic("ufs_lookup: .. through root");
+ #endif
+--- 140,149 ----
+ */
+ if (error = cache_lookup(ndp)) {
+ int vpid; /* capability number of vnode */
+!
+ if (error == ENOENT)
+ return (error);
+! #ifdef DIAGNOSTIC
+ if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot)
+ panic("ufs_lookup: .. through root");
+ #endif
+***************
+*** 186,192 ****
+ vdp = ITOV(dp);
+ ndp->ni_vp = NULL;
+ }
+!
+ /*
+ * If there is cached information on a previous search of
+ * this directory, pick up where we last left off.
+--- 185,201 ----
+ vdp = ITOV(dp);
+ ndp->ni_vp = NULL;
+ }
+!
+! len = ndp->ni_namelen;
+! name = ndp->ni_ptr;
+! /*
+! * 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.
+***************
+*** 205,219 ****
+ ndp->ni_ufs.ufs_offset = dp->i_diroff;
+ entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset);
+ if (entryoffsetinblock != 0) {
+! if (error = iso_blkatoff(dp, ndp->ni_ufs.ufs_offset,
+! (char **)0, &bp))
+! return (error);
+ }
+ numdirpasses = 2;
+! nchstats.ncs_2passes++;
+ }
+! endsearch = roundup(dp->i_size, imp->logical_block_size);
+!
+ searchloop:
+ while (ndp->ni_ufs.ufs_offset < endsearch) {
+ /*
+--- 214,227 ----
+ ndp->ni_ufs.ufs_offset = dp->i_diroff;
+ entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset);
+ if (entryoffsetinblock != 0) {
+! if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
+! return error;
+ }
+ numdirpasses = 2;
+! iso_nchstats.ncs_2passes++;
+ }
+! endsearch = roundup(dp->i_size,imp->logical_block_size);
+!
+ searchloop:
+ while (ndp->ni_ufs.ufs_offset < endsearch) {
+ /*
+***************
+*** 221,307 ****
+ * read the next directory block.
+ * Release previous if it exists.
+ */
+! if (iso_blkoff(imp, ndp->ni_ufs.ufs_offset) == 0) {
+ if (bp != NULL)
+ brelse(bp);
+! if (error = iso_blkatoff(dp, ndp->ni_ufs.ufs_offset,
+! (char **)0, &bp))
+! return (error);
+ entryoffsetinblock = 0;
+ }
+ /*
+ * Get pointer to next entry.
+ */
+!
+ ep = (struct iso_directory_record *)
+ (bp->b_un.b_addr + entryoffsetinblock);
+!
+ reclen = isonum_711 (ep->length);
+ if (reclen == 0) {
+ /* skip to next block, if any */
+ ndp->ni_ufs.ufs_offset =
+! roundup (ndp->ni_ufs.ufs_offset,
+! imp->logical_block_size);
+ continue;
+ }
+!
+! if (reclen < sizeof (struct iso_directory_record))
+ /* illegal entry, stop */
+ break;
+!
+! /* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size)
+ /* entries are not allowed to cross boundaries */
+ break;
+!
+ /*
+ * Check for a name match.
+ */
+! namelen = isonum_711 (ep->name_len);
+!
+! if (reclen < sizeof (struct iso_directory_record) + namelen)
+ /* illegal entry, stop */
+ break;
+!
+! if (namelen == 1
+! && ((ndp->ni_namelen == 1
+! && ndp->ni_ptr[0] == '.'
+! && ep->name[0] == 0)
+! || (ndp->ni_isdotdot && ep->name[0] == 1))) {
+! /*
+! * Save directory entry's inode number and
+! * reclen in ndp->ni_ufs area, and release
+! * directory buffer.
+! */
+! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent);
+! brelse(bp);
+! goto found;
+! } else {
+! switch ( imp->iso_ftype ) {
+! case ISO_FTYPE_9660:
+! if( ( namelen >= ndp->ni_namelen ) &&
+! ( isofncmp( ndp->ni_ptr, ndp->ni_namelen, ep->name, namelen ) ) ) {
+! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent);
+! brelse(bp);
+! goto found;
+! }
+! break;
+! case ISO_FTYPE_RRIP:
+! isofs_rrip_getname( ep, altname, &namelen );
+! if ( ( namelen == ndp->ni_namelen ) &&
+! ( !bcmp( ndp->ni_ptr, altname, ndp->ni_namelen ) ) ) {
+! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent);
+! brelse(bp);
+ goto found;
+ }
+! break;
+! default:
+! break;
+ }
+ }
+ ndp->ni_ufs.ufs_offset += reclen;
+ entryoffsetinblock += reclen;
+ }
+! /* notfound: */
+ /*
+ * If we started in the middle of the directory and failed
+ * to find our target, we must check the beginning as well.
+--- 229,345 ----
+ * read the next directory block.
+ * Release previous if it exists.
+ */
+! if (iso_blkoff(imp,ndp->ni_ufs.ufs_offset) == 0) {
+ if (bp != NULL)
+ brelse(bp);
+! if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
+! return error;
+ entryoffsetinblock = 0;
+ }
+ /*
+ * Get pointer to next entry.
+ */
+!
+ ep = (struct iso_directory_record *)
+ (bp->b_un.b_addr + entryoffsetinblock);
+!
+ reclen = isonum_711 (ep->length);
+ if (reclen == 0) {
+ /* skip to next block, if any */
+ ndp->ni_ufs.ufs_offset =
+! roundup(ndp->ni_ufs.ufs_offset,
+! 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;
+!
+ /*
+ * Check for a name match.
+ */
+! namelen = isonum_711(ep->name_len);
+!
+! if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
+ /* illegal entry, stop */
+ break;
+!
+! switch (imp->iso_ftype) {
+! default:
+! if ((!(isonum_711(ep->flags)&4)) == !assoc) {
+! if ((len == 1
+! && *name == '.')
+! || ndp->ni_isdotdot) {
+! if (namelen == 1
+! && ep->name[0] == (ndp->ni_isdotdot ? 1 : 0)) {
+! /*
+! * Save directory entry's inode number and
+! * reclen in ndp->ni_ufs area, and release
+! * directory buffer.
+! */
+! isodirino(&ndp->ni_ufs.ufs_ino,ep,imp);
+ goto found;
+ }
+! if (namelen != 1
+! || ep->name[0] != 0)
+! goto notfound;
+! } else if (!(res = isofncmp(name,len,
+! ep->name,namelen))) {
+! if (isonum_711(ep->flags)&2)
+! isodirino(&ino,ep,imp);
+! else
+! ino = (bp->b_blkno << DEV_BSHIFT)
+! + entryoffsetinblock;
+! saveoffset = ndp->ni_ufs.ufs_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)
++ isodirino(&ino,ep,imp);
++ else
++ ino = (bp->b_blkno << DEV_BSHIFT) + entryoffsetinblock;
++ ndp->ni_ufs.ufs_ino = ino;
++ isofs_rrip_getname(ep,altname,&namelen,&ndp->ni_ufs.ufs_ino,imp);
++ if (namelen == ndp->ni_namelen
++ && !bcmp(name,altname,namelen))
++ goto found;
++ ino = 0;
++ break;
+ }
+ ndp->ni_ufs.ufs_offset += reclen;
+ entryoffsetinblock += reclen;
+ }
+! if (ino) {
+! foundino:
+! ndp->ni_ufs.ufs_ino = ino;
+! if (saveoffset != ndp->ni_ufs.ufs_offset) {
+! if (iso_lblkno(imp,ndp->ni_ufs.ufs_offset)
+! != iso_lblkno(imp,saveoffset)) {
+! if (bp != NULL)
+! brelse(bp);
+! if (error = iso_blkatoff(dp,saveoffset,&bp))
+! return error;
+! }
+! ep = (struct iso_directory_record *)(bp->b_un.b_addr
+! + iso_blkoff(imp,saveoffset));
+! ndp->ni_ufs.ufs_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.
+***************
+*** 319,330 ****
+ */
+ if (ndp->ni_makeentry)
+ cache_enter(ndp);
+ return (ENOENT);
+!
+ found:
+! if (numdirpasses == 2)
+! nchstats.ncs_pass2++;
+!
+ /*
+ * Found component in pathname.
+ * If the final component of path name, save information
+--- 357,370 ----
+ */
+ if (ndp->ni_makeentry)
+ cache_enter(ndp);
++ if (flag == CREATE || flag == RENAME)
++ return EJUSTRETURN;
+ return (ENOENT);
+!
+ found:
+! if (numdirpasses > 1)
+! iso_nchstats.ncs_pass2++;
+!
+ /*
+ * Found component in pathname.
+ * If the final component of path name, save information
+***************
+*** 332,339 ****
+ */
+ if (*ndp->ni_next == '\0' && flag == LOOKUP)
+ dp->i_diroff = ndp->ni_ufs.ufs_offset;
+! /* &~ (imp->logical_block_size - 1); */
+!
+ /*
+ * Step through the translation in the name. We do not `iput' the
+ * directory because we may need it again if a symbolic link
+--- 372,378 ----
+ */
+ if (*ndp->ni_next == '\0' && flag == LOOKUP)
+ dp->i_diroff = ndp->ni_ufs.ufs_offset;
+!
+ /*
+ * Step through the translation in the name. We do not `iput' the
+ * directory because we may need it again if a symbolic link
+***************
+*** 354,364 ****
+ * that point backwards in the directory structure.
+ */
+ pdp = dp;
+ if (ndp->ni_isdotdot) {
+ ISO_IUNLOCK(pdp); /* race to get the inode */
+! if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep)) {
+ ISO_ILOCK(pdp);
+! return (error);
+ }
+ if (lockparent && *ndp->ni_next == '\0')
+ ISO_ILOCK(pdp);
+--- 393,410 ----
+ * that point backwards in the directory structure.
+ */
+ pdp = dp;
++ /*
++ * If ino is different from ndp->ni_ufs.ufs_ino,
++ * it's a relocated directory.
++ */
+ if (ndp->ni_isdotdot) {
+ ISO_IUNLOCK(pdp); /* race to get the inode */
+! if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
+! ndp->ni_ufs.ufs_ino != ino,
+! &tdp,ep)) {
+! brelse(bp);
+ ISO_ILOCK(pdp);
+! return error;
+ }
+ if (lockparent && *ndp->ni_next == '\0')
+ ISO_ILOCK(pdp);
+***************
+*** 367,388 ****
+ VREF(vdp); /* we want ourself, ie "." */
+ ndp->ni_vp = vdp;
+ } else {
+! if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep))
+! return (error);
+ if (!lockparent || *ndp->ni_next != '\0')
+ ISO_IUNLOCK(pdp);
+ ndp->ni_vp = ITOV(tdp);
+ }
+!
+ /*
+ * Insert name into cache if appropriate.
+ */
+ if (ndp->ni_makeentry)
+ cache_enter(ndp);
+! return (0);
+ }
+
+-
+ /*
+ * Return buffer with contents of block "offset"
+ * from the beginning of directory "ip". If "res"
+--- 413,439 ----
+ VREF(vdp); /* we want ourself, ie "." */
+ ndp->ni_vp = vdp;
+ } else {
+! if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
+! ndp->ni_ufs.ufs_ino != ino,
+! &tdp,ep)) {
+! brelse(bp);
+! return error;
+! }
+ if (!lockparent || *ndp->ni_next != '\0')
+ ISO_IUNLOCK(pdp);
+ ndp->ni_vp = ITOV(tdp);
+ }
+!
+! brelse(bp);
+!
+ /*
+ * Insert name into cache if appropriate.
+ */
+ if (ndp->ni_makeentry)
+ cache_enter(ndp);
+! return 0;
+ }
+
+ /*
+ * Return buffer with contents of block "offset"
+ * from the beginning of directory "ip". If "res"
+***************
+*** 390,415 ****
+ * remaining space in the directory.
+ */
+ int
+! iso_blkatoff(ip, offset, res, bpp)
+ struct iso_node *ip;
+ off_t offset;
+- char **res;
+ struct buf **bpp;
+ {
+ register struct iso_mnt *imp = ip->i_mnt;
+! daddr_t lbn = iso_lblkno (imp, offset);
+! int bsize = iso_blksize (imp, ip, lbn);
+ struct buf *bp;
+ int error;
+!
+! *bpp = 0;
+! if (error = bread(ITOV(ip), lbn, bsize, NOCRED, &bp)) {
+ brelse(bp);
+! return (error);
+ }
+- if (res)
+- *res = bp->b_un.b_addr + iso_blkoff(imp, offset);
+ *bpp = bp;
+!
+! return (0);
+ }
+--- 441,463 ----
+ * remaining space in the directory.
+ */
+ int
+! iso_blkatoff(ip, offset, bpp)
+ struct iso_node *ip;
+ off_t offset;
+ struct buf **bpp;
+ {
+ register struct iso_mnt *imp = ip->i_mnt;
+! daddr_t lbn = iso_lblkno(imp,offset);
+! int bsize = iso_blksize(imp,ip,lbn);
+ struct buf *bp;
+ int error;
+!
+! if (error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp)) {
+ brelse(bp);
+! *bpp = 0;
+! return error;
+ }
+ *bpp = bp;
+!
+! return 0;
+ }
+diff -cr sys/isofs/isofs_node.c src/sys/isofs/isofs_node.c
+*** sys/isofs/isofs_node.c Thu Nov 25 01:32:23 1993
+--- src/sys/isofs/isofs_node.c Mon Aug 15 15:58:28 1994
+***************
+*** 30,58 ****
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+! * from: @(#)isofs_inode.c
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+! #include "mount.h"
+! #include "proc.h"
+! #include "file.h"
+! #include "buf.h"
+! #include "vnode.h"
+! #include "kernel.h"
+! #include "malloc.h"
+!
+! #include "iso.h"
+! #include "isofs_node.h"
+! #include "iso_rrip.h"
+
+ #define INOHSZ 512
+ #if ((INOHSZ&(INOHSZ-1)) == 0)
+! #define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1))
+ #else
+! #define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ)
+ #endif
+
+ union iso_ihead {
+--- 30,65 ----
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+! * from: @(#)ufs_inode.c (unknown version)
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include <sys/param.h>
+! #include <sys/systm.h>
+! #include <sys/mount.h>
+! #include <sys/proc.h>
+! #include <sys/file.h>
+! #include <sys/buf.h>
+! #include <sys/vnode.h>
+! #include <sys/kernel.h>
+! #include <sys/malloc.h>
+! #include <sys/stat.h>
+!
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+! #include <isofs/iso_rrip.h>
+!
+! #define IFTOVT(mode) (iftovt_tab[((mode) & 0170000) >> 12])
+! static enum vtype iftovt_tab[16] = {
+! VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
+! VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
+! };
+
+ #define INOHSZ 512
+ #if ((INOHSZ&(INOHSZ-1)) == 0)
+! #define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))
+ #else
+! #define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)
+ #endif
+
+ union iso_ihead {
+***************
+*** 60,75 ****
+ struct iso_node *ih_chain[2];
+ } iso_ihead[INOHSZ];
+
+ int prtactive; /* 1 => print out reclaim of active vnodes */
+
+ /*
+! * Initialize hash links for inodes.
+ */
+ void
+ isofs_init()
+ {
+ register int i;
+ register union iso_ihead *ih = iso_ihead;
+
+ #ifndef lint
+ if (VN_MAXPRIVATE < sizeof(struct iso_node))
+--- 67,99 ----
+ struct iso_node *ih_chain[2];
+ } iso_ihead[INOHSZ];
+
++ #ifdef ISODEVMAP
++ #define DNOHSZ 64
++ #if ((DNOHSZ&(DNOHSZ-1)) == 0)
++ #define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))
++ #else
++ #define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)
++ #endif
++
++ union iso_dhead {
++ union iso_dhead *dh_head[2];
++ struct iso_dnode *dh_chain[2];
++ } iso_dhead[DNOHSZ];
++ #endif
++
+ int prtactive; /* 1 => print out reclaim of active vnodes */
+
+ /*
+! * Initialize hash links for inodes and dnodes.
+ */
+ void
+ isofs_init()
+ {
+ register int i;
+ register union iso_ihead *ih = iso_ihead;
++ #ifdef ISODEVMAP
++ register union iso_dhead *dh = iso_dhead;
++ #endif
+
+ #ifndef lint
+ if (VN_MAXPRIVATE < sizeof(struct iso_node))
+***************
+*** 79,86 ****
+--- 103,168 ----
+ ih->ih_head[0] = ih;
+ ih->ih_head[1] = ih;
+ }
++ #ifdef ISODEVMAP
++ for (i = DNOHSZ; --i >= 0; dh++) {
++ dh->dh_head[0] = dh;
++ dh->dh_head[1] = dh;
++ }
++ #endif
+ }
+
++ #ifdef ISODEVMAP
++ /*
++ * Enter a new node into the device hash list
++ */
++ struct iso_dnode *
++ iso_dmap(dev,ino,create)
++ dev_t dev;
++ ino_t ino;
++ int create;
++ {
++ struct iso_dnode *dp;
++ union iso_dhead *dh;
++
++ dh = &iso_dhead[DNOHASH(dev, ino)];
++ for (dp = dh->dh_chain[0];
++ dp != (struct iso_dnode *)dh;
++ dp = dp->d_forw)
++ if (ino == dp->i_number && dev == dp->i_dev)
++ return dp;
++
++ if (!create)
++ return (struct iso_dnode *)0;
++
++ MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK);
++ dp->i_dev = dev;
++ dp->i_number = ino;
++ insque(dp,dh);
++
++ return dp;
++ }
++
++ void
++ iso_dunmap(dev)
++ dev_t dev;
++ {
++ struct iso_dnode *dp, *dq;
++ union iso_dhead *dh;
++
++ for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) {
++ for (dp = dh->dh_chain[0];
++ dp != (struct iso_dnode *)dh;
++ dp = dq) {
++ dq = dp->d_forw;
++ if (dev == dp->i_dev) {
++ remque(dp);
++ FREE(dp,M_CACHE);
++ }
++ }
++ }
++ }
++ #endif
++
+ /*
+ * Look up a ISOFS dinode number to find its incore vnode.
+ * If it is not in core, read it in from the specified device.
+***************
+*** 89,112 ****
+ * points must be done by the calling routine.
+ */
+ int
+! iso_iget(xp, ino, ipp, isodir)
+ struct iso_node *xp;
+ ino_t ino;
+ struct iso_node **ipp;
+ struct iso_directory_record *isodir;
+ {
+ dev_t dev = xp->i_dev;
+ struct mount *mntp = ITOV(xp)->v_mount;
+! extern struct vnodeops isofs_vnodeops, spec_inodeops;
+ register struct iso_node *ip, *iq;
+ register struct vnode *vp;
+ struct vnode *nvp;
+! struct buf *bp;
+! struct dinode *dp;
+ union iso_ihead *ih;
+! int i, error, result = 0;
+ struct iso_mnt *imp;
+!
+ ih = &iso_ihead[INOHASH(dev, ino)];
+ loop:
+ for (ip = ih->ih_chain[0];
+--- 171,197 ----
+ * points must be done by the calling routine.
+ */
+ int
+! iso_iget(xp, ino, relocated, ipp, isodir)
+ struct iso_node *xp;
+ ino_t ino;
++ int relocated;
+ struct iso_node **ipp;
+ struct iso_directory_record *isodir;
+ {
+ dev_t dev = xp->i_dev;
+ struct mount *mntp = ITOV(xp)->v_mount;
+! extern struct vnodeops isofs_vnodeops, isofs_spec_inodeops;
+ register struct iso_node *ip, *iq;
+ register struct vnode *vp;
++ register struct iso_dnode *dp;
+ struct vnode *nvp;
+! struct buf *bp = NULL, *bp2 = NULL;
+ union iso_ihead *ih;
+! union iso_dhead *dh;
+! int i, error, result;
+ struct iso_mnt *imp;
+! ino_t defino;
+!
+ ih = &iso_ihead[INOHASH(dev, ino)];
+ loop:
+ for (ip = ih->ih_chain[0];
+***************
+*** 116,144 ****
+ continue;
+ if ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+! tsleep((caddr_t)ip, PINOD, "isoiget", 0);
+ goto loop;
+ }
+ if (vget(ITOV(ip)))
+ goto loop;
+ *ipp = ip;
+! return(0);
+ }
+ /*
+ * Allocate a new inode.
+ */
+ if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
+ *ipp = 0;
+! return (error);
+ }
+ ip = VTOI(nvp);
+ ip->i_vnode = nvp;
+ ip->i_flag = 0;
+ ip->i_devvp = 0;
+ ip->i_diroff = 0;
+- ip->iso_parent = xp->i_diroff; /* Parent directory's */
+- ip->iso_parent_ext = xp->iso_extent;
+ ip->i_lockf = 0;
+ /*
+ * Put it onto its hash chain and lock it so that other requests for
+ * this inode will block if they arrive while we are sleeping waiting
+--- 201,228 ----
+ continue;
+ if ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+! tsleep((caddr_t)ip, PINOD, "iget", 0);
+ goto loop;
+ }
+ if (vget(ITOV(ip)))
+ goto loop;
+ *ipp = ip;
+! return 0;
+ }
+ /*
+ * Allocate a new inode.
+ */
+ if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
+ *ipp = 0;
+! return error;
+ }
+ ip = VTOI(nvp);
+ ip->i_vnode = nvp;
+ ip->i_flag = 0;
+ ip->i_devvp = 0;
+ ip->i_diroff = 0;
+ ip->i_lockf = 0;
++
+ /*
+ * Put it onto its hash chain and lock it so that other requests for
+ * this inode will block if they arrive while we are sleeping waiting
+***************
+*** 150,209 ****
+ insque(ip, ih);
+ ISO_ILOCK(ip);
+
+- ip->iso_reclen = isonum_711 (isodir->length);
+- ip->iso_extlen = isonum_711 (isodir->ext_attr_length);
+- ip->iso_extent = isonum_733 (isodir->extent);
+- ip->i_size = isonum_733 (isodir->size);
+- ip->iso_flags = isonum_711 (isodir->flags);
+- ip->iso_unit_size = isonum_711 (isodir->file_unit_size);
+- ip->iso_interleave_gap = isonum_711 (isodir->interleave);
+- ip->iso_volume_seq = isonum_723 (isodir->volume_sequence_number);
+- ip->iso_namelen = isonum_711 (isodir->name_len);
+-
+ imp = VFSTOISOFS (mntp);
+ vp = ITOV(ip);
+ /*
+! * Setup time stamp, attribute , if CL or PL, set loc but not yet..
+ */
+! switch ( imp->iso_ftype ) {
+! case ISO_FTYPE_9660:
+! isofs_rrip_defattr ( isodir, &(ip->inode) );
+! isofs_rrip_deftstamp( isodir, &(ip->inode) );
+! goto FlameOff;
+! break;
+! case ISO_FTYPE_RRIP:
+! result = isofs_rrip_analyze( isodir, &(ip->inode) );
+! break;
+! default:
+! printf("unknown iso_ftype.. %d\n", imp->iso_ftype );
+! break;
+ }
+ /*
+ * Initialize the associated vnode
+ */
+! if ( result & ISO_SUSP_SLINK ) {
+! vp->v_type = VLNK; /* Symbolic Link */
+! } else {
+! FlameOff:
+! if (ip->iso_flags & 2) {
+! vp->v_type = VDIR;
+! } else {
+! vp->v_type = VREG;
+ }
+ }
+!
+! imp = VFSTOISOFS (mntp);
+!
+! if (ino == imp->root_extent)
+ vp->v_flag |= VROOT;
+! /*
+! * Finish inode initialization.
+! */
+! ip->i_mnt = imp;
+! ip->i_devvp = imp->im_devvp;
+! VREF(ip->i_devvp);
+ *ipp = ip;
+! return (0);
+ }
+
+ /*
+--- 234,343 ----
+ insque(ip, ih);
+ ISO_ILOCK(ip);
+
+ imp = VFSTOISOFS (mntp);
++ ip->i_mnt = imp;
++ ip->i_devvp = imp->im_devvp;
++ VREF(ip->i_devvp);
++
++ if (relocated) {
++ /*
++ * On relocated directories we must
++ * read the `.' entry out of a dir.
++ */
++ ip->iso_start = ino >> imp->im_bshift;
++ if (error = iso_blkatoff(ip,0,&bp)) {
++ vrele(ip->i_devvp);
++ remque(ip);
++ ip->i_forw = ip;
++ ip->i_back = ip;
++ iso_iput(ip);
++ *ipp = 0;
++ return error;
++ }
++ isodir = (struct iso_directory_record *)bp->b_un.b_addr;
++ }
++
++ 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;
++
+ vp = ITOV(ip);
++
+ /*
+! * Setup time stamp, attribute
+ */
+! vp->v_type = VNON;
+! switch (imp->iso_ftype) {
+! default: /* ISO_FTYPE_9660 */
+! if ((imp->im_flags&ISOFSMNT_EXTATT)
+! && isonum_711(isodir->ext_attr_length))
+! iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length),
+! &bp2);
+! isofs_defattr(isodir,ip,bp2 );
+! isofs_deftstamp(isodir,ip,bp2 );
+! break;
+! case ISO_FTYPE_RRIP:
+! result = isofs_rrip_analyze(isodir,ip,imp);
+! break;
+ }
++ if (bp2)
++ brelse(bp2);
++ if (bp)
++ brelse(bp);
++
+ /*
+ * Initialize the associated vnode
+ */
+! vp->v_type = IFTOVT(ip->inode.iso_mode);
+!
+! if ( vp->v_type == VFIFO ) {
+! #ifdef FIFO
+! extern struct vnodeops isofs_fifo_inodeops;
+! vp->v_op = &isofs_fifo_inodeops;
+! #else
+! iso_iput(ip);
+! *ipp = 0;
+! return EOPNOTSUPP;
+! #endif /* FIFO */
+! } else if ( vp->v_type == VCHR || vp->v_type == VBLK ) {
+! /*
+! * if device, look at device number table for translation
+! */
+! #ifdef ISODEVMAP
+! if (dp = iso_dmap(dev,ino,0))
+! ip->inode.iso_rdev = dp->d_dev;
+! #endif
+! vp->v_op = &isofs_spec_inodeops;
+! if (nvp = checkalias(vp, ip->inode.iso_rdev, mntp)) {
+! /*
+! * Reinitialize aliased inode.
+! */
+! vp = nvp;
+! iq = VTOI(vp);
+! iq->i_vnode = vp;
+! iq->i_flag = 0;
+! ISO_ILOCK(iq);
+! iq->i_dev = dev;
+! iq->i_number = ino;
+! iq->i_mnt = ip->i_mnt;
+! bcopy(&ip->iso_extent,&iq->iso_extent,
+! (char *)(ip + 1) - (char *)&ip->iso_extent);
+! insque(iq, ih);
+! /*
+! * Discard unneeded vnode
+! * (This introduces the need of INACTIVE modification)
+! */
+! ip->inode.iso_mode = 0;
+! iso_iput(ip);
+! ip = iq;
+ }
+ }
+!
+! if (ip->iso_extent == imp->root_extent)
+ vp->v_flag |= VROOT;
+!
+ *ipp = ip;
+! return 0;
+ }
+
+ /*
+***************
+*** 213,219 ****
+ iso_iput(ip)
+ register struct iso_node *ip;
+ {
+!
+ if ((ip->i_flag & ILOCKED) == 0)
+ panic("iso_iput");
+ ISO_IUNLOCK(ip);
+--- 347,353 ----
+ iso_iput(ip)
+ register struct iso_node *ip;
+ {
+!
+ if ((ip->i_flag & ILOCKED) == 0)
+ panic("iso_iput");
+ ISO_IUNLOCK(ip);
+***************
+*** 231,256 ****
+ {
+ register struct iso_node *ip = VTOI(vp);
+ int mode, error = 0;
+!
+ if (prtactive && vp->v_usecount != 0)
+ vprint("isofs_inactive: pushing active", vp);
+!
+ ip->i_flag = 0;
+ /*
+ * If we are done with the inode, reclaim it
+ * so that it can be reused immediately.
+ */
+!
+! /*
+! * Purge symlink entries since they cause problems
+! * when cached. Leave other entries alone since flushing
+! * them every time is a major performance hit.
+! */
+! if (vp->v_usecount == 0 && vp->v_type == VLNK) {
+! /* printf("Flushing symlink entry\n");*/
+ vgone(vp);
+! }
+! return (error);
+ }
+
+ /*
+--- 365,382 ----
+ {
+ register struct iso_node *ip = VTOI(vp);
+ int mode, error = 0;
+!
+ if (prtactive && vp->v_usecount != 0)
+ vprint("isofs_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 (vp->v_usecount == 0 && ip->inode.iso_mode == 0)
+ vgone(vp);
+! return error;
+ }
+
+ /*
+***************
+*** 262,268 ****
+ {
+ register struct iso_node *ip = VTOI(vp);
+ int i;
+!
+ if (prtactive && vp->v_usecount != 0)
+ vprint("isofs_reclaim: pushing active", vp);
+ /*
+--- 388,394 ----
+ {
+ register struct iso_node *ip = VTOI(vp);
+ int i;
+!
+ if (prtactive && vp->v_usecount != 0)
+ vprint("isofs_reclaim: pushing active", vp);
+ /*
+***************
+*** 280,286 ****
+ ip->i_devvp = 0;
+ }
+ ip->i_flag = 0;
+! return (0);
+ }
+
+ /*
+--- 406,412 ----
+ ip->i_devvp = 0;
+ }
+ ip->i_flag = 0;
+! return 0;
+ }
+
+ /*
+***************
+*** 290,302 ****
+ iso_ilock(ip)
+ register struct iso_node *ip;
+ {
+!
+ while (ip->i_flag & ILOCKED) {
+ ip->i_flag |= IWANT;
+ if (ip->i_spare0 == curproc->p_pid)
+ panic("locking against myself");
+ ip->i_spare1 = curproc->p_pid;
+! (void) tsleep((caddr_t)ip, PINOD, "isoilck", 0);
+ }
+ ip->i_spare1 = 0;
+ ip->i_spare0 = curproc->p_pid;
+--- 416,428 ----
+ iso_ilock(ip)
+ register struct iso_node *ip;
+ {
+!
+ while (ip->i_flag & ILOCKED) {
+ ip->i_flag |= IWANT;
+ if (ip->i_spare0 == curproc->p_pid)
+ panic("locking against myself");
+ ip->i_spare1 = curproc->p_pid;
+! (void) tsleep((caddr_t)ip, PINOD, "ilock", 0);
+ }
+ ip->i_spare1 = 0;
+ ip->i_spare0 = curproc->p_pid;
+***************
+*** 319,322 ****
+--- 445,650 ----
+ ip->i_flag &= ~IWANT;
+ wakeup((caddr_t)ip);
+ }
++ }
++
++ /*
++ * File attributes
++ */
++ void
++ isofs_defattr(isodir,inop,bp)
++ struct iso_directory_record *isodir;
++ struct iso_node *inop;
++ struct buf *bp;
++ {
++ struct buf *bp2 = NULL;
++ struct iso_mnt *imp;
++ struct iso_extended_attributes *ap = NULL;
++ int off;
++
++ if (isonum_711(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))) {
++ iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
++ bp = bp2;
++ }
++ if (bp) {
++ ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
++
++ 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
++ isofs_deftstamp(isodir,inop,bp)
++ struct iso_directory_record *isodir;
++ struct iso_node *inop;
++ struct buf *bp;
++ {
++ 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))) {
++ iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
++ bp = bp2;
++ }
++ if (bp) {
++ ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
++
++ if (isonum_711(ap->version) == 1) {
++ if (!isofs_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
++ isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
++ if (!isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
++ inop->inode.iso_ctime = inop->inode.iso_atime;
++ if (!isofs_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
++ inop->inode.iso_mtime = inop->inode.iso_ctime;
++ } else
++ ap = NULL;
++ }
++ if (!ap) {
++ isofs_tstamp_conv7(isodir->date,&inop->inode.iso_ctime);
++ inop->inode.iso_atime = inop->inode.iso_ctime;
++ inop->inode.iso_mtime = inop->inode.iso_ctime;
++ }
++ if (bp2)
++ brelse(bp2);
++ }
++
++ int
++ isofs_tstamp_conv7(pi,pu)
++ char *pi;
++ struct timeval *pu;
++ {
++ int i;
++ 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];
++ tz = pi[6];
++
++ if (y < 1970) {
++ pu->tv_sec = 0;
++ pu->tv_usec = 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_usec = 0;
++ return 1;
++ }
++
++ static unsigned
++ isofs_chars2ui(begin,len)
++ unsigned char *begin;
++ int len;
++ {
++ unsigned rc;
++
++ for (rc = 0; --len >= 0;) {
++ rc *= 10;
++ rc += *begin++ - '0';
++ }
++ return rc;
++ }
++
++ int
++ isofs_tstamp_conv17(pi,pu)
++ unsigned char *pi;
++ struct timeval *pu;
++ {
++ unsigned char buf[7];
++
++ /* year:"0001"-"9999" -> -1900 */
++ buf[0] = isofs_chars2ui(pi,4) - 1900;
++
++ /* month: " 1"-"12" -> 1 - 12 */
++ buf[1] = isofs_chars2ui(pi + 4,2);
++
++ /* day: " 1"-"31" -> 1 - 31 */
++ buf[2] = isofs_chars2ui(pi + 6,2);
++
++ /* hour: " 0"-"23" -> 0 - 23 */
++ buf[3] = isofs_chars2ui(pi + 8,2);
++
++ /* minute:" 0"-"59" -> 0 - 59 */
++ buf[4] = isofs_chars2ui(pi + 10,2);
++
++ /* second:" 0"-"59" -> 0 - 59 */
++ buf[5] = isofs_chars2ui(pi + 12,2);
++
++ /* difference of GMT */
++ buf[6] = pi[16];
++
++ return isofs_tstamp_conv7(buf,pu);
++ }
++
++ void
++ isodirino(inump,isodir,imp)
++ ino_t *inump;
++ struct iso_directory_record *isodir;
++ struct iso_mnt *imp;
++ {
++ *inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
++ * imp->logical_block_size;
+ }
+diff -cr sys/isofs/isofs_node.h src/sys/isofs/isofs_node.h
+*** sys/isofs/isofs_node.h Sun Dec 19 00:51:04 1993
+--- src/sys/isofs/isofs_node.h Mon Aug 15 15:17:56 1994
+***************
+*** 1,22 ****
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISOFS_NODE_H_
+ #define _ISOFS_ISOFS_NODE_H_ 1
+
+-
+ typedef struct {
+- unsigned iso_cln; /* Child link */
+- unsigned iso_pln; /* Parents link */
+ struct timeval iso_atime; /* time of last access */
+ struct timeval iso_mtime; /* time of last modification */
+ struct timeval 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 */
+ } ISO_RRIP_INODE;
+
+ struct iso_node {
+ struct iso_node *i_chain[2]; /* hash chain, MUST be first */
+ struct vnode *i_vnode; /* vnode associated with this inode */
+--- 1,35 ----
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISOFS_NODE_H_
+ #define _ISOFS_ISOFS_NODE_H_ 1
+
+ typedef struct {
+ struct timeval iso_atime; /* time of last access */
+ struct timeval iso_mtime; /* time of last modification */
+ struct timeval 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;
+
++ #ifdef ISODEVMAP
++ /*
++ * FOr device# (major,minor) translation table
++ */
++ struct iso_dnode {
++ struct iso_dnode *d_chain[2]; /* hash chain, MUST be first */
++ dev_t i_dev; /* device where dnode resides */
++ ino_t i_number; /* the identity of the inode */
++ dev_t d_dev; /* device # for translation */
++ };
++ #define d_forw d_chain[0]
++ #define d_back d_chain[1]
++ #endif
++
+ struct iso_node {
+ struct iso_node *i_chain[2]; /* hash chain, MUST be first */
+ struct vnode *i_vnode; /* vnode associated with this inode */
+***************
+*** 24,29 ****
+--- 37,43 ----
+ u_long i_flag; /* see below */
+ dev_t i_dev; /* device where inode resides */
+ 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 */
+ long i_diroff; /* offset in dir, where we found last entry */
+***************
+*** 31,48 ****
+ long i_spare0;
+ long i_spare1;
+
+!
+! int iso_reclen;
+! int iso_extlen;
+! int iso_extent;
+! int i_size;
+! int iso_flags;
+! int iso_unit_size;
+! int iso_interleave_gap;
+! int iso_volume_seq;
+! int iso_namelen; /* ISO9660/RRIP name len */
+! int iso_parent; /* byte offset in beginning of dir record */
+! int iso_parent_ext; /* block number of dir record */
+ ISO_RRIP_INODE inode;
+ };
+
+--- 45,54 ----
+ long i_spare0;
+ long i_spare1;
+
+! long iso_extent; /* extent of file */
+! 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;
+ };
+
+***************
+*** 92,108 ****
+ int isofs_strategy __P((struct buf *bp));
+ void isofs_print __P((struct vnode *vp));
+ int isofs_islocked __P((struct vnode *vp));
+!
+! /* From isofs_node.c: */
+! struct iso_directory_record;
+! extern void isofs_init(void);
+! extern int iso_iget(struct iso_node *, ino_t, struct iso_node **,
+! struct iso_directory_record *);
+! extern void iso_iput(struct iso_node *);
+! extern void iso_ilock(struct iso_node *);
+! extern void iso_iunlock(struct iso_node *);
+!
+!
+! extern int iso_blkatoff(struct iso_node *, off_t, char **, struct buf **);
+
+ #endif /* _ISOFS_ISOFS_NODE_H_ */
+--- 98,110 ----
+ int isofs_strategy __P((struct buf *bp));
+ void isofs_print __P((struct vnode *vp));
+ int isofs_islocked __P((struct vnode *vp));
+! void isofs_defattr __P((struct iso_directory_record *isodir,
+! struct iso_node *inop, struct buf *bp));
+! void isofs_deftstamp __P((struct iso_directory_record *isodir,
+! struct iso_node *inop, struct buf *bp));
+! #ifdef ISODEVMAP
+! struct iso_dnode *iso_dmap __P((dev_t dev, ino_t ino, int create));
+! void iso_dunmap __P((dev_t dev));
+! #endif
+
+ #endif /* _ISOFS_ISOFS_NODE_H_ */
+diff -cr sys/isofs/isofs_rrip.c src/sys/isofs/isofs_rrip.c
+*** sys/isofs/isofs_rrip.c Mon Jun 13 21:19:35 1994
+--- src/sys/isofs/isofs_rrip.c Mon Aug 15 15:38:56 1994
+***************
+*** 28,664 ****
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+! #include "namei.h"
+! #include "buf.h"
+! #include "file.h"
+! #include "vnode.h"
+! #include "mount.h"
+! #include "kernel.h"
+!
+! #include "sys/time.h"
+!
+! #include "iso.h"
+! #include "isofs_node.h"
+! #include "isofs_rrip.h"
+! #include "iso_rrip.h"
+
+ /*
+ * POSIX file attribute
+ */
+! 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); */
+! return 0;
+! }
+!
+! int isofs_rrip_defattr( isodir, ana )
+! struct iso_directory_record *isodir;
+! ISO_RRIP_ANALYZE *ana;
+! {
+! ana->inode.iso_mode = (VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6);
+! ana->inode.iso_uid = (uid_t)0;
+! ana->inode.iso_gid = (gid_t)0;
+! return 0;
+ }
+
+! /*
+! * POSIX device modes
+! */
+! static int isofs_rrip_device( p, ana )
+! ISO_RRIP_DEVICE *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! char buf[3];
+!
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+!
+! 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)
+! );
+! return 0;
+ }
+
+ /*
+ * Symbolic Links
+ */
+! static int isofs_rrip_slink( p, ana )
+ ISO_RRIP_SLINK *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+ return 0;
+ }
+
+ /*
+ * Alternate name
+ */
+! static int isofs_rrip_altname( p, ana )
+ ISO_RRIP_ALTNAME *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+ return 0;
+ }
+
+! /*
+! * Child Link
+! */
+! static int isofs_rrip_clink( p, ana )
+! ISO_RRIP_CLINK *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! char buf[3];
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+! printf("isofs:%s[%d] loc=%d\n",
+! buf,
+! isonum_711(p->h.length),
+! isonum_733(p->dir_loc)
+! );
+! ana->inode.iso_cln = isonum_733(p->dir_loc);
+! return 0;
+ }
+
+ /*
+! * Parent Link
+ */
+! static int isofs_rrip_plink( p, ana )
+! ISO_RRIP_PLINK *p;
+! ISO_RRIP_ANALYZE *ana;
+! {
+!
+! char buf[3];
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+! printf("isofs:%s[%d] loc=%d\n",
+! buf,
+! isonum_711(p->h.length),
+! isonum_733(p->dir_loc)
+! );
+! ana->inode.iso_pln = isonum_733(p->dir_loc);
+! return 0;
+ }
+
+ /*
+ * Relocated directory
+ */
+! static int isofs_rrip_reldir( p, ana )
+! ISO_RRIP_RELDIR *p;
+! ISO_RRIP_ANALYZE *ana;
+ {
+! char buf[3];
+!
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+!
+! printf("isofs:%s[%d]\n",buf, isonum_711(p->h.length) );
+! return 0;
+! }
+!
+! /*
+! * Time stamp
+! */
+! static void isofs_rrip_tstamp_conv7(pi, pu)
+! char *pi;
+! struct timeval *pu;
+! {
+! int i;
+! int crtime,days;
+! int year,month,day,hour,minute,second,tz;
+!
+! year = pi[0] - 70;
+! month = pi[1];
+! day = pi[2];
+! hour = pi[3];
+! minute = pi[4];
+! second = pi[5];
+! tz = pi[6];
+!
+! if (year < 0) {
+! crtime = 0;
+! } else {
+! static int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
+!
+! days = year * 365;
+! if (year > 2)
+! days += (year+2) / 4;
+! for (i = 1; i < month; i++)
+! days += monlen[i-1];
+! if (((year+2) % 4) == 0 && month > 2)
+! days++;
+! days += day - 1;
+! crtime = ((((days * 24) + hour) * 60 + minute) * 60)
+! + second;
+!
+! /* sign extend */
+! if (tz & 0x80)
+! tz |= (-1 << 8);
+!
+! /* timezone offset is unreliable on some disks */
+! if (-48 <= tz && tz <= 52)
+! crtime -= tz * 15 * 60;
+! }
+! pu->tv_sec = crtime;
+! pu->tv_usec = 0;
+ }
+
+!
+! static unsigned isofs_chars2ui( begin, end )
+! unsigned char *begin;
+! unsigned char *end;
+ {
+! unsigned rc=0;
+! int len;
+! int wlen;
+! static int pow[]={ 1, 10, 100, 1000 };
+!
+! len = end - begin;
+! wlen= len;
+! for (; len >= 0; len -- ) {
+! rc += ( *(begin+len) * pow[wlen - len] );
+! }
+! return( rc );
+! }
+
+- static void isofs_rrip_tstamp_conv17(pi, pu)
+- unsigned char *pi;
+- struct timeval *pu;
+- {
+- unsigned char buf[7];
+-
+- /* year:"0001"-"9999" -> -1900 */
+- buf[0] = (unsigned char)(isofs_chars2ui( &pi[0], &pi[3]) - 1900 );
+-
+- /* month: " 1"-"12" -> 1 - 12 */
+- buf[1] = (unsigned char)isofs_chars2ui( &pi[4], &pi[5]);
+-
+- /* day: " 1"-"31" -> 1 - 31 */
+- buf[2] = isofs_chars2ui( &pi[6], &pi[7]);
+-
+- /* hour: " 0"-"23" -> 0 - 23 */
+- buf[3] = isofs_chars2ui( &pi[8], &pi[9]);
+-
+- /* minute:" 0"-"59" -> 0 - 59 */
+- buf[4] = isofs_chars2ui( &pi[10], &pi[11] );
+-
+- /* second:" 0"-"59" -> 0 - 59 */
+- buf[5] = isofs_chars2ui( &pi[12], &pi[13] );
+-
+- /* difference of GMT */
+- buf[6] = pi[16];
+-
+- isofs_rrip_tstamp_conv7(buf, pu);
+- }
+-
+- static int isofs_rrip_tstamp( p, ana )
+- ISO_RRIP_TSTAMP *p;
+- ISO_RRIP_ANALYZE *ana;
+- {
+- unsigned char *ptime;
+-
+ ptime = p->time;
+!
+ /* Check a format of time stamp (7bytes/17bytes) */
+! if ( !(*p->flags & ISO_SUSP_TSTAMP_FORM17 ) ) {
+! isofs_rrip_tstamp_conv7(ptime, &ana->inode.iso_ctime );
+!
+! if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY )
+! isofs_rrip_tstamp_conv7(ptime+7, &ana->inode.iso_mtime );
+! else
+! ana->inode.iso_mtime = ana->inode.iso_ctime;
+!
+! if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS )
+! isofs_rrip_tstamp_conv7(ptime+14, &ana->inode.iso_atime );
+! else
+! ana->inode.iso_atime = ana->inode.iso_ctime;
+ } else {
+! isofs_rrip_tstamp_conv17(ptime, &ana->inode.iso_ctime );
+!
+! if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY )
+! isofs_rrip_tstamp_conv17(ptime+17, &ana->inode.iso_mtime );
+! else
+! ana->inode.iso_mtime = ana->inode.iso_ctime;
+!
+! if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS )
+! isofs_rrip_tstamp_conv17(ptime+34, &ana->inode.iso_atime );
+! else
+! ana->inode.iso_atime = ana->inode.iso_ctime;
+ }
+! return 0;
+ }
+
+! int isofs_rrip_deftstamp( isodir, ana )
+ struct iso_directory_record *isodir;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! isofs_rrip_tstamp_conv7(isodir->date, &ana->inode.iso_ctime );
+! ana->inode.iso_atime = ana->inode.iso_ctime;
+! ana->inode.iso_mtime = ana->inode.iso_ctime;
+! return 0;
+ }
+
+
+ /*
+ * Flag indicating
+- * Nothing to do....
+ */
+! static int isofs_rrip_idflag( p, ana )
+! ISO_RRIP_IDFLAG *p;
+! ISO_RRIP_ANALYZE *ana;
+! {
+! char buf[3];
+!
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+!
+! printf("isofs:%s[%d] idflag=0x%x\n",
+! buf,
+! isonum_711(p->h.length),
+! p->flags );
+! return 0;
+ }
+
+ /*
+! * Extension reference
+! * Nothing to do....
+ */
+! static int isofs_rrip_exflag( p, ana )
+! ISO_RRIP_EXFLAG *p;
+! ISO_RRIP_ANALYZE *ana;
+! {
+! char buf[3];
+!
+! buf[0] = p->h.type[0];
+! buf[1] = p->h.type[1];
+! buf[2] = 0x00;
+!
+! printf("isofs:%s[%d] exflag=0x%x",
+! buf,
+! isonum_711(p->h.length),
+! p->flags );
+! return 0;
+ }
+
+ /*
+! * Unknown ...
+! * Nothing to do....
+ */
+! static int isofs_rrip_unknown( p, ana )
+! ISO_RRIP_EXFLAG *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! return 0;
+ }
+
+ typedef struct {
+! char type[2];
+! int (*func)();
+! int (*func2)();
+! int result;
+ } RRIP_TABLE;
+
+! static RRIP_TABLE rrip_table [] = {
+! { 'P', 'X', isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR },
+! { 'T', 'F', isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP },
+! { 'N', 'M', isofs_rrip_altname,0, ISO_SUSP_ALTNAME },
+! { 'C', 'L', isofs_rrip_clink, 0, ISO_SUSP_CLINK },
+! { 'P', 'L', isofs_rrip_plink, 0, ISO_SUSP_PLINK },
+! { 'S', 'L', isofs_rrip_slink, 0, ISO_SUSP_SLINK },
+! { 'R', 'E', isofs_rrip_reldir, 0, ISO_SUSP_RELDIR },
+! { 'P', 'N', isofs_rrip_device, 0, ISO_SUSP_DEVICE },
+! { '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 }
+! };
+!
+! int isofs_rrip_analyze ( isodir, analyze )
+! struct iso_directory_record *isodir;
+! ISO_RRIP_ANALYZE *analyze;
+! {
+! register RRIP_TABLE *ptable;
+ register ISO_SUSP_HEADER *phead;
+ register ISO_SUSP_HEADER *pend;
+! int found;
+! int i;
+! char *pwhead;
+! 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) & 0x0001) )
+! pwhead ++;
+! phead = (ISO_SUSP_HEADER *)pwhead;
+! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
+!
+ result = 0;
+! if ( pend == phead ) {
+! goto setdefault;
+! }
+! /*
+! * Note: "pend" should be more than one SUSP header
+! */
+! while ( pend >= phead + 1) {
+! found = 0;
+! for ( ptable=&rrip_table[0];ptable < &rrip_table[sizeof(rrip_table)/sizeof(RRIP_TABLE)]; ptable ++) {
+! if ( bcmp( phead->type, ptable->type, 2 ) == 0 ) {
+! found = 1;
+! ptable->func( phead, analyze );
+! result |= ptable->result;
+! break;
+ }
+! }
+! if ( found == 0 ) {
+! printf("isofs: name '");
+! for ( i =0; i < isonum_711(isodir->name_len) ;i++) {
+! printf("%c", *(isodir->name + i) );
+ }
+! printf("'");
+! printf(" - type %c%c [%08x/%08x]...not found\n",
+! phead->type[0], phead->type[1], phead, pend );
+! isofs_hexdump( phead, (int)( (char *)pend - (char *)phead ) );
+! break;
+! }
+!
+! /*
+! * move to next SUSP
+! */
+! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
+ }
+!
+! setdefault:
+ /*
+ * If we don't find the Basic SUSP stuffs, just set default value
+! * ( attribute/time stamp )
+ */
+! for ( ptable=&rrip_table[0];ptable < &rrip_table[2]; ptable ++) {
+! if ( ptable->func2 != 0 && !(ptable->result & result) ) {
+! ptable->func2( isodir, analyze );
+! }
+! }
+! return ( result );
+ }
+
+! /*
+! * Get Alternate Name from 'AL' record
+! * If either no AL record nor 0 lenght,
+! * it will be return the translated ISO9660 name,
+ */
+! int isofs_rrip_getname( isodir, outbuf, outlen )
+ struct iso_directory_record *isodir;
+! char *outbuf;
+! int *outlen;
+ {
+! ISO_SUSP_HEADER *phead, *pend;
+! ISO_RRIP_ALTNAME *p;
+! char *pwhead;
+! int found;
+!
+! /*
+! * 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) & 0x0001) )
+! pwhead ++;
+! phead = (ISO_SUSP_HEADER *)pwhead;
+! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
+!
+! found = 0;
+! if ( pend != phead ) {
+! while ( pend >= phead + 1) {
+! if ( bcmp( phead->type, "NM", 2 ) == 0 ) {
+! found = 1;
+! break;
+! }
+! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
+! }
+! }
+! if ( found == 1 ) {
+! p = (ISO_RRIP_ALTNAME *)phead;
+! *outlen = isonum_711( p->h.length ) - sizeof( ISO_RRIP_ALTNAME );
+! bcopy( (char *)( &p->flags + 1 ), outbuf, *outlen );
+! } else {
+! isofntrans(isodir->name, isonum_711(isodir->name_len), outbuf, outlen );
+! if ( *outlen == 1) {
+! switch ( outbuf[0] ) {
+! case 0:
+! outbuf[0] = '.';
+! break;
+! case 1:
+! outbuf[0] = '.';
+! outbuf[1] = '.';
+! *outlen = 2;
+! }
+! }
+! }
+! return( found );
+ }
+
+ /*
+! * Get Symbolic Name from 'SL' record
+! *
+! * Note: isodir should contains SL record!
+! */
+! int isofs_rrip_getsymname( vp, isodir, outbuf, outlen )
+! struct vnode *vp;
+! struct iso_directory_record *isodir;
+! char *outbuf;
+! int *outlen;
+! {
+! register ISO_RRIP_SLINK_COMPONENT *pcomp;
+! register ISO_SUSP_HEADER *phead, *pend;
+! register ISO_RRIP_SLINK_COMPONENT *pcompe;
+! ISO_RRIP_SLINK *p;
+! char *pwhead;
+! int found;
+! int slash;
+! int wlen;
+
+! /*
+! * 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) & 0x0001) )
+! pwhead ++;
+! phead = (ISO_SUSP_HEADER *)pwhead;
+! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
+!
+! found = 0;
+! if ( pend != phead ) {
+! while ( pend >= phead + 1) {
+! if ( bcmp( phead->type, "SL", 2 ) == 0 ) {
+! found = 1;
+! break;
+! }
+! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
+! }
+ }
+- if ( found == 0 ) {
+- *outlen = 0;
+- return( found );
+- }
+-
+- p = (ISO_RRIP_SLINK *)phead;
+- pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
+- pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
+
+! /*
+! * Gathering a Symbolic name from each component with path
+! */
+! *outlen = 0;
+! slash = 0;
+! while ( pcomp < pcompe ) {
+!
+! /* Inserting Current */
+! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_CURRENT ) {
+! bcopy("./", outbuf+*outlen, 2);
+! *outlen += 2;
+! slash = 0;
+! }
+
+! /* Inserting Parent */
+! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_PARENT ) {
+! bcopy("../", outbuf+*outlen, 3);
+! *outlen += 3;
+! slash = 0;
+! }
+
+! /* Inserting slash for ROOT */
+! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_ROOT ) {
+! bcopy("/", outbuf+*outlen, 1);
+! *outlen += 1;
+! slash = 0;
+! }
+
+! /* Inserting a mount point i.e. "/cdrom" */
+! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_VOLROOT ) {
+! wlen = strlen(vp->v_mount->mnt_stat.f_mntonname);
+! bcopy(vp->v_mount->mnt_stat.f_mntonname,outbuf+*outlen, wlen);
+! *outlen += wlen;
+! slash = 1;
+! }
+
+! /* Inserting hostname i.e. "tama:" */
+! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_HOST ) {
+! bcopy(hostname, outbuf+*outlen, hostnamelen);
+! *(outbuf+hostnamelen) = ':';
+! *outlen += (hostnamelen + 1);
+! slash = 0; /* Uuum Should we insert a slash ? */
+! }
+
+! /* Inserting slash for next component */
+! if ( slash == 1 ) {
+! outbuf[*outlen] = '/';
+! *outlen += 1;
+! slash = 0;
+! }
+!
+! /* Inserting component */
+! wlen = isonum_711(pcomp->clen);
+! if ( wlen != 0 ) {
+! bcopy( pcomp->name, outbuf + *outlen, wlen );
+! *outlen += wlen;
+! slash = 1;
+! }
+!
+! /*
+! * Move to next component...
+! */
+! pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp
+! + sizeof(ISO_RRIP_SLINK_COMPONENT) - 1
+! + isonum_711(pcomp->clen));
+! }
+! return( found );
+! }
+! /* Hexdump routine for debug*/
+! int isofs_hexdump( p, size )
+! unsigned char *p;
+! int size;
+! {
+! int i,j,k;
+! unsigned char *wp;
+!
+! for ( i = 0; i < size; i += 16 ) {
+! printf("isofs: ");
+! wp = p;
+! k = ( (size - i) > 16 ? 16 : size - i );
+! for ( j =0; j < k; j ++ ){
+! printf("%02x ", *p );
+! p++;
+! }
+! printf(" : ");
+! p = wp;
+! for ( j =0; j < k; j ++ ){
+! if ( (*p > 0x20) && (*p < 0x7f) )
+! printf("%c", *p );
+! else
+! printf(" ");
+! p++;
+! }
+! printf("\n");
+ }
+! printf("\n");
+! return 0;
+ }
+--- 28,681 ----
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include <sys/param.h>
+! #include <sys/systm.h>
+! #include <sys/namei.h>
+! #include <sys/buf.h>
+! #include <sys/file.h>
+! #include <sys/vnode.h>
+! #include <sys/mount.h>
+! #include <sys/kernel.h>
+! #include <sys/stat.h>
+! #include <sys/types.h>
+! #include <sys/time.h>
+!
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+! #include <isofs/isofs_rrip.h>
+! #include <isofs/iso_rrip.h>
+
+ /*
+ * POSIX file attribute
+ */
+! static int
+! isofs_rrip_attr(p,ana)
+! ISO_RRIP_ATTR *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! ana->inop->inode.iso_mode = isonum_731(p->mode_l);
+! ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l);
+! ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l);
+! ana->inop->inode.iso_links = isonum_731(p->links_l);
+! ana->fields &= ~ISO_SUSP_ATTR;
+! return ISO_SUSP_ATTR;
+ }
+
+! static void
+! isofs_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");
+! isofs_defattr(isodir,ana->inop,NULL);
+ }
+
+ /*
+ * Symbolic Links
+ */
+! static int
+! isofs_rrip_slink(p,ana)
+ ISO_RRIP_SLINK *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
++ register ISO_RRIP_SLINK_COMPONENT *pcomp;
++ register 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 */
++ /* start over from beginning(?) */
++ outbuf -= len;
++ len = 0;
++ 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 = hostnamelen;
++ break;
++
++ case ISO_SUSP_CFLAG_CONTINUE:
++ cont = 1;
++ /* fall thru */
++ 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
+! isofs_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 = hostnamelen;
++ break;
++
++ case ISO_SUSP_CFLAG_CONTINUE:
++ cont = 1;
++ /* fall thru */
++ 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
+! isofs_rrip_defname(isodir,ana)
+! struct iso_directory_record *isodir;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! strcpy(ana->outbuf,"..");
+! switch (*isodir->name) {
+! default:
+! isofntrans(isodir->name,isonum_711(isodir->name_len),
+! ana->outbuf,ana->outlen,
+! 1,isonum_711(isodir->flags)&4);
+! break;
+! case 0:
+! *ana->outlen = 1;
+! break;
+! case 1:
+! *ana->outlen = 2;
+! break;
+! }
+ }
+
+ /*
+! * Parent or Child Link
+ */
+! static int
+! isofs_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
+! isofs_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
+! isofs_rrip_tstamp(p,ana)
+! ISO_RRIP_TSTAMP *p;
+! ISO_RRIP_ANALYZE *ana;
+ {
+! unsigned 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) {
+! isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime);
+! ptime += 7;
+! } else
+! bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval));
+!
+! if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
+! isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_atime);
+! ptime += 7;
+! } else
+! ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
+!
+! if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
+! isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime);
+! 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) {
+! isofs_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime);
+! ptime += 17;
+! } else
+! bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval));
+!
+! if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
+! isofs_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)
+! isofs_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
+! isofs_rrip_deftstamp(isodir,ana)
+ struct iso_directory_record *isodir;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! isofs_deftstamp(isodir,ana->inop,NULL);
+ }
+
++ /*
++ * POSIX device modes
++ */
++ static int
++ isofs_rrip_device(p,ana)
++ ISO_RRIP_DEVICE *p;
++ ISO_RRIP_ANALYZE *ana;
++ {
++ unsigned high, low;
++
++ high = isonum_733(p->dev_t_high_l);
++ low = isonum_733(p->dev_t_low_l);
++
++ if (high == 0)
++ ana->inop->inode.iso_rdev = makedev(major(low),minor(low));
++ else
++ ana->inop->inode.iso_rdev = makedev(high,minor(low));
++ ana->fields &= ~ISO_SUSP_DEVICE;
++ return ISO_SUSP_DEVICE;
++ }
+
+ /*
+ * Flag indicating
+ */
+! static int
+! isofs_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 isofs_rrip_reldir(p,ana);
+!
+! return ISO_SUSP_IDFLAG;
+ }
+
+ /*
+! * Continuation pointer
+ */
+! static int
+! isofs_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
+! isofs_rrip_stop(p,ana)
+! ISO_SUSP_HEADER *p;
+ ISO_RRIP_ANALYZE *ana;
+ {
+! return ISO_SUSP_STOP;
+! }
+!
+! /*
+! * Extension reference
+! */
+! static int
+! isofs_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;
+ }
+
+ typedef struct {
+! char type[2];
+! int (*func)();
+! void (*func2)();
+! int result;
+ } RRIP_TABLE;
+
+! static int
+! isofs_rrip_loop(isodir,ana,table)
+! struct iso_directory_record *isodir;
+! ISO_RRIP_ANALYZE *ana;
+! RRIP_TABLE *table;
+! {
+! register RRIP_TABLE *ptable;
+ register ISO_SUSP_HEADER *phead;
+ register ISO_SUSP_HEADER *pend;
+! struct buf *bp = NULL;
+! int i;
+! char *pwhead;
+! 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++;
+!
+! /* If it's not the '.' entry of the root dir obey SP field */
+! if (*isodir->name != 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->logical_block_size / DEV_BSIZE,
+! ana->imp->logical_block_size,NOCRED,&bp))
+! /* what to do now? */
+! break;
+! phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + 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.
+ */
+! static RRIP_TABLE rrip_table_analyze[] = {
+! { "PX", isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR },
+! { "TF", isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP },
+! { "PN", isofs_rrip_device, 0, ISO_SUSP_DEVICE },
+! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG },
+! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT },
+! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP },
+! { "", 0, 0, 0 }
+! };
+!
+! int
+! isofs_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 isofs_rrip_loop(isodir,&analyze,rrip_table_analyze);
+ }
+
+ /*
+! * Get Alternate Name.
+! */
+! static RRIP_TABLE rrip_table_getname[] = {
+! { "NM", isofs_rrip_altname, isofs_rrip_defname, ISO_SUSP_ALTNAME },
+! { "CL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
+! { "PL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
+! { "RE", isofs_rrip_reldir, 0, ISO_SUSP_RELDIR },
+! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG },
+! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT },
+! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP },
+! { "", 0, 0, 0 }
+! };
+
+! int
+! isofs_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;
+!
+! 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;
+!
+! tab = rrip_table_getname;
+! if (*isodir->name == 0
+! || *isodir->name == 1) {
+! isofs_rrip_defname(isodir,&analyze);
+!
+! analyze.fields &= ~ISO_SUSP_ALTNAME;
+! tab++;
+ }
+
+! return isofs_rrip_loop(isodir,&analyze,tab);
+! }
+
+! /*
+! * Get Symbolic Link.
+! */
+! static RRIP_TABLE rrip_table_getsymname[] = {
+! { "SL", isofs_rrip_slink, 0, ISO_SUSP_SLINK },
+! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG },
+! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT },
+! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP },
+! { "", 0, 0, 0 }
+! };
+
+! int
+! isofs_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 (isofs_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK);
+! }
+
+! static RRIP_TABLE rrip_table_extref[] = {
+! { "ER", isofs_rrip_extref, 0, ISO_SUSP_EXTREF },
+! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT },
+! { "ST", isofs_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
+! isofs_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 (!(isofs_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF))
+! return -1;
+!
+! return isonum_711(p->skip);
+ }
+diff -cr sys/isofs/isofs_rrip.h src/sys/isofs/isofs_rrip.h
+*** sys/isofs/isofs_rrip.h Sun Nov 7 17:46:05 1993
+--- src/sys/isofs/isofs_rrip.h Mon Aug 15 15:17:57 1994
+***************
+*** 29,35 ****
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isofs_rrip.h
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISOFS_RRIP_H_
+--- 29,35 ----
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isofs_rrip.h
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+ #ifndef _ISOFS_ISOFS_RRIP_H_
+***************
+*** 71,78 ****
+ typedef struct {
+ u_char cflag [ISODCL ( 1, 1)];
+ u_char clen [ISODCL ( 2, 2)];
+! u_char name [ISODCL ( 3, 3)];
+ } ISO_RRIP_SLINK_COMPONENT;
+
+ typedef struct {
+ ISO_SUSP_HEADER h;
+--- 71,79 ----
+ typedef struct {
+ u_char cflag [ISODCL ( 1, 1)];
+ u_char clen [ISODCL ( 2, 2)];
+! u_char name [0];
+ } ISO_RRIP_SLINK_COMPONENT;
++ #define ISO_RRIP_SLSIZ 2
+
+ typedef struct {
+ ISO_SUSP_HEADER h;
+***************
+*** 122,128 ****
+
+ typedef struct {
+ ISO_SUSP_HEADER h;
+! unsigned char flags [ISODCL ( 4, 4)];
+! } ISO_RRIP_EXFLAG;
+
+ #endif /* _ISOFS_ISOFS_RRIP_H_ */
+--- 123,145 ----
+
+ 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;
+
+ #endif /* _ISOFS_ISOFS_RRIP_H_ */
+diff -cr sys/isofs/isofs_util.c src/sys/isofs/isofs_util.c
+*** sys/isofs/isofs_util.c Sun Dec 19 00:51:06 1993
+--- src/sys/isofs/isofs_util.c Mon Aug 15 15:17:57 1994
+***************
+*** 1,139 ****
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+
+ int
+ isonum_711 (p)
+! char *p;
+ {
+! return (*p & 0xff);
+ }
+
+ int
+ isonum_712 (p)
+! char *p;
+ {
+! int val;
+!
+! val = *p;
+! if (val & 0x80)
+! val |= ~0xff;
+! return (val);
+ }
+
+ int
+ isonum_721 (p)
+! char *p;
+ {
+! return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+ }
+
+ int
+ isonum_722 (p)
+! char *p;
+ {
+! return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
+ }
+
+ int
+ isonum_723 (p)
+! char *p;
+ {
+! #if 0
+! if (p[0] != p[3] || p[1] != p[2]) {
+! fprintf (stderr, "invalid format 7.2.3 number\n");
+! exit (1);
+! }
+ #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));
+ }
+
+ int
+ isonum_732 (p)
+ unsigned char *p;
+ {
+! return (((p[0] & 0xff) << 24)
+! | ((p[1] & 0xff) << 16)
+! | ((p[2] & 0xff) << 8)
+! | (p[3] & 0xff));
+ }
+
+ 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);
+! }
+! }
+ #endif
+- return (isonum_731 (p));
+ }
+
+ /*
+ * translate and compare a filename
+ */
+ int
+! isofncmp(char *fn, int fnlen, char *isofn, int isolen) {
+! int fnidx;
+!
+! fnidx = 0;
+! for (fnidx = 0; fnidx < isolen; fnidx++, fn++) {
+! char c = *isofn++;
+!
+! if (fnidx > fnlen)
+! return (0);
+!
+! if (c >= 'A' && c <= 'Z') {
+! if (c + ('a' - 'A') != *fn)
+! return(0);
+! else
+! continue;
+ }
+- if (c == ';')
+- return ((fnidx == fnlen));
+- if (c != *fn)
+- return (0);
+ }
+! return (1);
+ }
+
+ /*
+ * translate a filename
+ */
+ void
+! isofntrans(char *infn, int infnlen, char *outfn, short *outfnlen) {
+! int fnidx;
+!
+! fnidx = 0;
+! for (fnidx = 0; fnidx < infnlen; fnidx++) {
+ char c = *infn++;
+!
+! if (c >= 'A' && c <= 'Z')
+ *outfn++ = c + ('a' - 'A');
+! else if (c == ';') {
+! *outfnlen = fnidx;
+! return;
+! } else
+ *outfn++ = c;
+ }
+! *outfnlen = infnlen;
+ }
+--- 1,203 ----
+ /*
+! * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include <sys/param.h>
+! #include <sys/systm.h>
+! #include <sys/namei.h>
+! #include <sys/resourcevar.h>
+! #include <sys/kernel.h>
+! #include <sys/file.h>
+! #include <sys/stat.h>
+! #include <sys/buf.h>
+! #include <sys/proc.h>
+! #include <sys/conf.h>
+! #include <sys/mount.h>
+! #include <sys/vnode.h>
+! #include <sys/malloc.h>
+! #include <sys/dir.h>
+
++ #include <sys/specdev.h> /* XXX */
++ #include <sys/fifo.h> /* XXX */
++
++ #include <isofs/iso.h>
++
++ #include <machine/endian.h>
++
++ #ifdef __notanymore__
+ int
+ isonum_711 (p)
+! unsigned char *p;
+ {
+! return (*p);
+ }
+
+ int
+ isonum_712 (p)
+! signed char *p;
+ {
+! return (*p);
+ }
+
+ int
+ isonum_721 (p)
+! unsigned char *p;
+ {
+! /* 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)
+! unsigned char *p;
+ {
+! /* 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)
+! unsigned char *p;
+ {
+! #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
+ }
+
+ int
+ isonum_731 (p)
+ unsigned char *p;
+ {
+! /* 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;
+ {
+! /* 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;
+ {
+! #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
+ }
++ #endif /* __notanymore__ */
+
+ /*
+ * translate and compare a filename
++ * Note: Version number plus ';' may be omitted.
+ */
+ int
+! isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen)
+! {
+! int i, j;
+! unsigned char c;
+!
+! while (--fnlen >= 0) {
+! if (--isolen < 0)
+! return *fn;
+! if ((c = *isofn++) == ';') {
+! switch (*fn++) {
+! default:
+! return *--fn;
+! case 0:
+! return 0;
+! case ';':
+! break;
+! }
+! for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') {
+! if (*fn < '0' || *fn > '9') {
+! return -1;
+! }
+! }
+! for (j = 0; --isolen >= 0; j = j * 10 + *isofn++ - '0');
+! return i - j;
+! }
+! if (c != *fn) {
+! if (c >= 'A' && c <= 'Z') {
+! if (c + ('a' - 'A') != *fn) {
+! if (*fn >= 'a' && *fn <= 'z')
+! return *fn - ('a' - 'A') - c;
+! else
+! return *fn - c;
+! }
+! } else
+! return *fn - c;
+! }
+! fn++;
+! }
+! if (isolen > 0) {
+! switch (*isofn) {
+! default:
+! return -1;
+! case '.':
+! if (isofn[1] != ';')
+! return -1;
+! case ';':
+! return 0;
+ }
+ }
+! return 0;
+ }
+
+ /*
+ * translate a filename
+ */
+ void
+! isofntrans(unsigned char *infn,int infnlen,
+! unsigned char *outfn,unsigned short *outfnlen,
+! int original,int assoc)
+! {
+! int fnidx = 0;
+!
+! if (assoc) {
+! *outfn++ = ASSOCCHAR;
+! fnidx++;
+! }
+! for (; fnidx < infnlen; fnidx++) {
+ char c = *infn++;
+!
+! if (!original && c >= 'A' && c <= 'Z')
+ *outfn++ = c + ('a' - 'A');
+! else if (!original && c == '.' && *infn == ';')
+! break;
+! else if (!original && c == ';')
+! break;
+! else
+ *outfn++ = c;
+ }
+! *outfnlen = fnidx;
+ }
+diff -cr sys/isofs/isofs_vfsops.c src/sys/isofs/isofs_vfsops.c
+*** sys/isofs/isofs_vfsops.c Thu Jun 2 07:48:34 1994
+--- src/sys/isofs/isofs_vfsops.c Tue Aug 16 16:26:34 1994
+***************
+*** 1,25 ****
+ /*
+ * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+
+! #include "param.h"
+! #include "systm.h"
+! #include "namei.h"
+! #include "proc.h"
+! #include "kernel.h"
+! #include "vnode.h"
+! #include "specdev.h"
+! #include "mount.h"
+! #include "buf.h"
+! #include "file.h"
+! #include "dkbad.h"
+! #include "disklabel.h"
+! #include "ioctl.h"
+! #include "errno.h"
+! #include "malloc.h"
+!
+! #include "iso.h"
+! #include "isofs_node.h"
+
+ extern int enodev ();
+
+--- 1,25 ----
+ /*
+ * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
++ #include <sys/param.h>
++ #include <sys/systm.h>
++ #include <sys/namei.h>
++ #include <sys/proc.h>
++ #include <sys/kernel.h>
++ #include <sys/vnode.h>
++ #include <sys/mount.h>
++ #include <sys/buf.h>
++ #include <sys/file.h>
++ #include <sys/dkbad.h>
++ #include <sys/disklabel.h>
++ #include <sys/ioctl.h>
++ #include <sys/errno.h>
++ #include <sys/malloc.h>
++
++ #include <sys/specdev.h> /* XXX */
+
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+
+ extern int enodev ();
+
+***************
+*** 37,49 ****
+ };
+
+ /*
+! * Called by vfs_mountroot when ufs is going to be mounted as root.
+ *
+ * Name is updated by mount(8) after booting.
+ */
+ #define ROOTNAME "root_device"
+
+! static int iso_mountfs(struct vnode *, struct mount *, struct proc *);
+
+ int
+ isofs_mountroot()
+--- 37,49 ----
+ };
+
+ /*
+! * Called by vfs_mountroot when iso is going to be mounted as root.
+ *
+ * Name is updated by mount(8) after booting.
+ */
+ #define ROOTNAME "root_device"
+
+! static iso_mountfs();
+
+ int
+ isofs_mountroot()
+***************
+*** 55,76 ****
+ register struct fs *fs;
+ u_int size;
+ int error;
+!
+ mp = (struct mount *)malloc((u_long)sizeof(struct mount),
+ M_MOUNT, M_WAITOK);
+! mp->mnt_op = &isofs_vfsops;
+ mp->mnt_flag = MNT_RDONLY;
+ mp->mnt_exroot = 0;
+ mp->mnt_mounth = NULLVP;
+! error = iso_mountfs(rootvp, mp, p);
+ if (error) {
+ free((caddr_t)mp, M_MOUNT);
+! return (error);
+ }
+ if (error = vfs_lock(mp)) {
+ (void)isofs_unmount(mp, 0, p);
+ free((caddr_t)mp, M_MOUNT);
+! return (error);
+ }
+ rootfs = mp;
+ mp->mnt_next = mp;
+--- 55,78 ----
+ register struct fs *fs;
+ u_int size;
+ int error;
+! struct iso_args args;
+!
+ mp = (struct mount *)malloc((u_long)sizeof(struct mount),
+ M_MOUNT, M_WAITOK);
+! mp->mnt_op = (struct vfsops *)&isofs_vfsops;
+ mp->mnt_flag = MNT_RDONLY;
+ mp->mnt_exroot = 0;
+ mp->mnt_mounth = NULLVP;
+! args.flags = ISOFSMNT_ROOT;
+! error = iso_mountfs(rootvp, mp, p, &args);
+ if (error) {
+ free((caddr_t)mp, M_MOUNT);
+! return error;
+ }
+ if (error = vfs_lock(mp)) {
+ (void)isofs_unmount(mp, 0, p);
+ free((caddr_t)mp, M_MOUNT);
+! return error;
+ }
+ rootfs = mp;
+ mp->mnt_next = mp;
+***************
+*** 86,101 ****
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void) isofs_statfs(mp, &mp->mnt_stat, p);
+ vfs_unlock(mp);
+! return (0);
+ }
+
+ /*
+! * Flag to allow forcible unmounting.
+ */
+ int iso_doforce = 1;
+
+ /*
+! * VFS Operations.
+ *
+ * mount system call
+ */
+--- 88,104 ----
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void) isofs_statfs(mp, &mp->mnt_stat, p);
+ vfs_unlock(mp);
+! return 0;
+ }
+
++
+ /*
+! * flag to allow forcible unmounting.
+ */
+ int iso_doforce = 1;
+
+ /*
+! * vfs operations.
+ *
+ * mount system call
+ */
+***************
+*** 108,133 ****
+ struct proc *p;
+ {
+ struct vnode *devvp;
+! struct ufs_args args;
+ u_int size;
+ int error;
+! struct iso_mnt *imp = 0;
+!
+! if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
+! return (error);
+!
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+! return (EROFS);
+!
+ /*
+! * Process export requests.
+ */
+! if ((args.exflags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) {
+! if (args.exflags & MNT_EXPORTED)
+ mp->mnt_flag |= MNT_EXPORTED;
+ else
+ mp->mnt_flag &= ~MNT_EXPORTED;
+! if (args.exflags & MNT_EXRDONLY)
+ mp->mnt_flag |= MNT_EXRDONLY;
+ else
+ mp->mnt_flag &= ~MNT_EXRDONLY;
+--- 111,136 ----
+ struct proc *p;
+ {
+ struct vnode *devvp;
+! struct iso_args args;
+ u_int size;
+ int error;
+! struct iso_mnt *imp;
+!
+! if (error = copyin(data, (caddr_t)&args, sizeof (struct iso_args)))
+! return error;
+!
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+! return EROFS;
+!
+ /*
+! * Process export requests.
+ */
+! if ((args.flags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) {
+! if (args.flags & MNT_EXPORTED)
+ mp->mnt_flag |= MNT_EXPORTED;
+ else
+ mp->mnt_flag &= ~MNT_EXPORTED;
+! if (args.flags & MNT_EXRDONLY)
+ mp->mnt_flag |= MNT_EXRDONLY;
+ else
+ mp->mnt_flag &= ~MNT_EXRDONLY;
+***************
+*** 138,146 ****
+ * read/write; if there is no device name, that's all we do.
+ */
+ if (mp->mnt_flag & MNT_UPDATE) {
+- imp = VFSTOISOFS(mp);
+ if (args.fspec == 0)
+! return (0);
+ }
+ /*
+ * Not an update, or updating the name: look up the name
+--- 141,148 ----
+ * read/write; if there is no device name, that's all we do.
+ */
+ if (mp->mnt_flag & MNT_UPDATE) {
+ if (args.fspec == 0)
+! return 0;
+ }
+ /*
+ * Not an update, or updating the name: look up the name
+***************
+*** 150,169 ****
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = args.fspec;
+ if (error = namei(ndp, p))
+! return (error);
+ devvp = ndp->ni_vp;
+ if (devvp->v_type != VBLK) {
+ vrele(devvp);
+! return (ENOTBLK);
+ }
+ if (major(devvp->v_rdev) >= nblkdev) {
+ vrele(devvp);
+! return (ENXIO);
+ }
+!
+! if ((mp->mnt_flag & MNT_UPDATE) == 0)
+! error = iso_mountfs(devvp, mp, p);
+! else {
+ if (devvp != imp->im_devvp)
+ error = EINVAL; /* needs translation */
+ else
+--- 152,172 ----
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = args.fspec;
+ if (error = namei(ndp, p))
+! return error;
+ devvp = ndp->ni_vp;
+ if (devvp->v_type != VBLK) {
+ vrele(devvp);
+! return ENOTBLK;
+ }
+ if (major(devvp->v_rdev) >= nblkdev) {
+ vrele(devvp);
+! return ENXIO;
+ }
+!
+! if ((mp->mnt_flag & MNT_UPDATE) == 0) {
+! error = iso_mountfs(devvp, mp, p, &args);
+! } else {
+! imp = VFSTOISOFS(mp);
+ if (devvp != imp->im_devvp)
+ error = EINVAL; /* needs translation */
+ else
+***************
+*** 171,208 ****
+ }
+ if (error) {
+ vrele(devvp);
+! return (error);
+ }
+ imp = VFSTOISOFS(mp);
+!
+! /* Check the Rock Ridge Extention support */
+! if ( args.exflags & MNT_NORRIP ) {
+! imp->iso_ftype = ISO_FTYPE_9660;
+! mp->mnt_flag |= MNT_NORRIP;
+! } else {
+! imp->iso_ftype = ISO_FTYPE_RRIP;
+! mp->mnt_flag &= ~MNT_NORRIP;
+! }
+!
+ (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &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);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void) isofs_statfs(mp, &mp->mnt_stat, p);
+! return (0);
+ }
+
+ /*
+ * Common code for mount and mountroot
+ */
+! static int
+! iso_mountfs(devvp, mp, p)
+ register struct vnode *devvp;
+ struct mount *mp;
+ struct proc *p;
+ {
+ register struct iso_mnt *isomp = (struct iso_mnt *)0;
+ struct buf *bp = NULL;
+--- 174,202 ----
+ }
+ if (error) {
+ vrele(devvp);
+! return error;
+ }
+ imp = VFSTOISOFS(mp);
+!
+ (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &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);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void) isofs_statfs(mp, &mp->mnt_stat, p);
+! return 0;
+ }
+
+ /*
+ * Common code for mount and mountroot
+ */
+! static int iso_mountfs(devvp, mp, p, argp)
+ register struct vnode *devvp;
+ struct mount *mp;
+ struct proc *p;
++ struct iso_args *argp;
+ {
+ register struct iso_mnt *isomp = (struct iso_mnt *)0;
+ struct buf *bp = NULL;
+***************
+*** 220,310 ****
+ struct iso_primary_descriptor *pri;
+ struct iso_directory_record *rootp;
+ int logical_block_size;
+!
+ if (!ronly)
+! return (EROFS);
+!
+ /*
+ * Disallow multiple mounts of the same device.
+ * Disallow mounting of a device that is currently in use
+ * (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))
+! return (error);
+ if (vcount(devvp) > 1 && devvp != rootvp)
+! return (EBUSY);
+ vinvalbuf(devvp, 1);
+ if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
+! return (error);
+ needclose = 1;
+!
+ /* This is the "logical sector size". The standard says this
+ * should be 2048 or the physical sector size on the device,
+ * whichever is greater. For now, we'll just use a constant.
+ */
+ iso_bsize = 2048;
+!
+ for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
+ if (error = bread (devvp, iso_blknum * iso_bsize / DEV_BSIZE,
+ iso_bsize, NOCRED, &bp))
+ goto out;
+!
+ vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
+ if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
+ error = EINVAL;
+ goto out;
+ }
+!
+ if (isonum_711 (vdp->type) == ISO_VD_END) {
+ error = EINVAL;
+ goto out;
+ }
+!
+ if (isonum_711 (vdp->type) == ISO_VD_PRIMARY)
+ break;
+ brelse(bp);
+ }
+!
+ if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
+ error = EINVAL;
+ goto out;
+ }
+
+ pri = (struct iso_primary_descriptor *)vdp;
+!
+ logical_block_size = isonum_723 (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 *)pri->root_directory_record;
+!
+ isomp = (struct iso_mnt *)malloc(sizeof *isomp,M_ISOFSMNT,M_WAITOK);
+ isomp->logical_block_size = logical_block_size;
+ isomp->volume_space_size = isonum_733 (pri->volume_space_size);
+ bcopy (rootp, isomp->root, sizeof isomp->root);
+ isomp->root_extent = isonum_733 (rootp->extent);
+ isomp->root_size = isonum_733 (rootp->size);
+!
+! isomp->im_bsize = logical_block_size;
+! isomp->im_bmask = ~(isomp->im_bsize - 1);
+ isomp->im_bshift = 0;
+! while ((1 << isomp->im_bshift) < isomp->im_bsize)
+ isomp->im_bshift++;
+!
+! bp->b_flags |= B_INVAL;
+ brelse(bp);
+ bp = NULL;
+!
+! isomp->im_ronly = ronly;
+! if (ronly == 0)
+! isomp->im_fmod = 1;
+!
+ mp->mnt_data = (qaddr_t)isomp;
+ mp->mnt_stat.f_fsid.val[0] = (long)dev;
+ mp->mnt_stat.f_fsid.val[1] = MOUNT_ISOFS;
+--- 214,299 ----
+ struct iso_primary_descriptor *pri;
+ struct iso_directory_record *rootp;
+ int logical_block_size;
+!
+ if (!ronly)
+! return EROFS;
+!
+ /*
+ * Disallow multiple mounts of the same device.
+ * Disallow mounting of a device that is currently in use
+ * (except for root, which might share swap device for miniroot).
+ * Flush out any old buffers remaining from a previous use.
+ */
+! if (error = mountedon(devvp))
+! return error;
+ if (vcount(devvp) > 1 && devvp != rootvp)
+! return EBUSY;
+ vinvalbuf(devvp, 1);
+ if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
+! return error;
+ needclose = 1;
+!
+ /* This is the "logical sector size". The standard says this
+ * should be 2048 or the physical sector size on the device,
+ * whichever is greater. For now, we'll just use a constant.
+ */
+ iso_bsize = 2048;
+!
+ for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
+ if (error = bread (devvp, iso_blknum * iso_bsize / DEV_BSIZE,
+ iso_bsize, NOCRED, &bp))
+ goto out;
+!
+ vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
+ if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
+ error = EINVAL;
+ goto out;
+ }
+!
+ if (isonum_711 (vdp->type) == ISO_VD_END) {
+ error = EINVAL;
+ goto out;
+ }
+!
+ if (isonum_711 (vdp->type) == ISO_VD_PRIMARY)
+ break;
+ brelse(bp);
+ }
+!
+ if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
+ error = EINVAL;
+ goto out;
+ }
+
+ pri = (struct iso_primary_descriptor *)vdp;
+!
+ logical_block_size = isonum_723 (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 *)pri->root_directory_record;
+!
+ isomp = (struct iso_mnt *)malloc(sizeof *isomp,M_ISOFSMNT,M_WAITOK);
+ isomp->logical_block_size = logical_block_size;
+ isomp->volume_space_size = isonum_733 (pri->volume_space_size);
+ 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 = 0;
+! while ((1 << isomp->im_bshift) < isomp->logical_block_size)
+ isomp->im_bshift++;
+!
+! bp->b_flags |= B_AGE;
+ brelse(bp);
+ bp = NULL;
+!
+ mp->mnt_data = (qaddr_t)isomp;
+ mp->mnt_stat.f_fsid.val[0] = (long)dev;
+ mp->mnt_stat.f_fsid.val[1] = MOUNT_ISOFS;
+***************
+*** 312,321 ****
+ isomp->im_mountp = mp;
+ isomp->im_dev = dev;
+ isomp->im_devvp = devvp;
+!
+ devvp->v_specflags |= SI_MOUNTEDON;
+!
+! return (0);
+ out:
+ if (bp)
+ brelse(bp);
+--- 301,347 ----
+ isomp->im_mountp = mp;
+ isomp->im_dev = dev;
+ isomp->im_devvp = devvp;
+!
+ devvp->v_specflags |= SI_MOUNTEDON;
+!
+! /* Check the Rock Ridge Extention support */
+! if (!(argp->flags & ISOFSMNT_NORRIP)) {
+! if (error = bread (isomp->im_devvp,
+! (isomp->root_extent + isonum_711(rootp->ext_attr_length))
+! * isomp->logical_block_size / DEV_BSIZE,
+! isomp->logical_block_size,NOCRED,&bp))
+! goto out;
+!
+! rootp = (struct iso_directory_record *)bp->b_un.b_addr;
+!
+! if ((isomp->rr_skip = isofs_rrip_offset(rootp,isomp)) < 0) {
+! argp->flags |= ISOFSMNT_NORRIP;
+! } else {
+! argp->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;
+! }
+! isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT);
+! 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:
+! isomp->iso_ftype = ISO_FTYPE_RRIP;
+! break;
+! }
+!
+! return 0;
+ out:
+ if (bp)
+ brelse(bp);
+***************
+*** 325,331 ****
+ free((caddr_t)isomp, M_ISOFSMNT);
+ mp->mnt_data = (qaddr_t)0;
+ }
+! return (error);
+ }
+
+ /*
+--- 351,357 ----
+ free((caddr_t)isomp, M_ISOFSMNT);
+ mp->mnt_data = (qaddr_t)0;
+ }
+! return error;
+ }
+
+ /*
+***************
+*** 339,346 ****
+ int flags;
+ struct proc *p;
+ {
+!
+! return (0);
+ }
+
+ /*
+--- 365,371 ----
+ int flags;
+ struct proc *p;
+ {
+! return 0;
+ }
+
+ /*
+***************
+*** 354,404 ****
+ {
+ register struct iso_mnt *isomp;
+ int i, error, ronly, flags = 0;
+!
+ if (mntflags & MNT_FORCE) {
+ if (!iso_doforce || mp == rootfs)
+! return (EINVAL);
+ flags |= FORCECLOSE;
+ }
+ mntflushbuf(mp, 0);
+ if (mntinvalbuf(mp))
+! return (EBUSY);
+ isomp = VFSTOISOFS(mp);
+!
+ if (error = vflush(mp, NULLVP, flags))
+! return (error);
+! ronly = !isomp->im_ronly;
+ isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
+! error = VOP_CLOSE(isomp->im_devvp, ronly ? FREAD : FREAD|FWRITE,
+! NOCRED, p);
+ vrele(isomp->im_devvp);
+ free((caddr_t)isomp, M_ISOFSMNT);
+ mp->mnt_data = (qaddr_t)0;
+ mp->mnt_flag &= ~MNT_LOCAL;
+! return (error);
+! }
+!
+! /*
+! * Check to see if a filesystem is mounted on a block device.
+! */
+! int
+! iso_mountedon(vp)
+! register struct vnode *vp;
+! {
+! register struct vnode *vq;
+!
+! if (vp->v_specflags & SI_MOUNTEDON)
+! return (EBUSY);
+! if (vp->v_flag & VALIASED) {
+! for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+! if (vq->v_rdev != vp->v_rdev ||
+! vq->v_type != vp->v_type)
+! continue;
+! if (vq->v_specflags & SI_MOUNTEDON)
+! return (EBUSY);
+! }
+! }
+! return (0);
+ }
+
+ /*
+--- 379,409 ----
+ {
+ register struct iso_mnt *isomp;
+ int i, error, ronly, flags = 0;
+!
+ if (mntflags & MNT_FORCE) {
+ if (!iso_doforce || mp == rootfs)
+! return EINVAL;
+ flags |= FORCECLOSE;
+ }
+ mntflushbuf(mp, 0);
+ if (mntinvalbuf(mp))
+! return EBUSY;
+ isomp = VFSTOISOFS(mp);
+!
+ if (error = vflush(mp, NULLVP, flags))
+! return error;
+! #ifdef ISODEVMAP
+! if (isomp->iso_ftype == ISO_FTYPE_RRIP)
+! iso_dunmap(isomp->im_dev);
+! #endif
+!
+ isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
+! error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p);
+ vrele(isomp->im_devvp);
+ free((caddr_t)isomp, M_ISOFSMNT);
+ mp->mnt_data = (qaddr_t)0;
+ mp->mnt_flag &= ~MNT_LOCAL;
+! return error;
+ }
+
+ /*
+***************
+*** 414,432 ****
+ struct vnode tvp;
+ int error;
+ struct iso_mnt *imp = VFSTOISOFS (mp);
+!
+ tvp.v_mount = mp;
+ ip = VTOI(&tvp);
+ ip->i_vnode = &tvp;
+ ip->i_dev = imp->im_dev;
+ ip->i_diroff = 0;
+! ip->iso_extent = imp->root_extent;
+! error = iso_iget(ip, imp->root_extent, &nip,
+! (struct iso_directory_record *) imp->root);
+ if (error)
+! return (error);
+ *vpp = ITOV(nip);
+! return (0);
+ }
+
+ /*
+--- 419,445 ----
+ struct vnode tvp;
+ int error;
+ struct iso_mnt *imp = VFSTOISOFS (mp);
+! struct iso_directory_record *dp;
+!
+ tvp.v_mount = mp;
+ ip = VTOI(&tvp);
+ ip->i_vnode = &tvp;
+ ip->i_dev = imp->im_dev;
+ ip->i_diroff = 0;
+! dp = (struct iso_directory_record *)imp->root;
+! isodirino(&ip->i_number,dp,imp);
+!
+! /*
+! * With RRIP we must use the `.' entry of the root directory.
+! * Simply tell iget, that it's a relocated directory.
+! */
+! error = iso_iget(ip,ip->i_number,
+! imp->iso_ftype == ISO_FTYPE_RRIP,
+! &nip,dp);
+ if (error)
+! return error;
+ *vpp = ITOV(nip);
+! return 0;
+ }
+
+ /*
+***************
+*** 457,463 ****
+ bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
+ (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
+ }
+! return (0);
+ }
+
+ int
+--- 470,480 ----
+ bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
+ (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
+ }
+! #if 0
+! /* Use the first spare for flags: */
+! sbp->f_spare[0] = isomp->im_flags;
+! #endif
+! return 0;
+ }
+
+ int
+***************
+*** 465,471 ****
+ struct mount *mp;
+ int waitfor;
+ {
+! return (0);
+ }
+
+ /*
+--- 482,488 ----
+ struct mount *mp;
+ int waitfor;
+ {
+! return 0;
+ }
+
+ /*
+***************
+*** 478,490 ****
+ * - check that the generation number matches
+ */
+
+-
+ struct ifid {
+ ushort ifid_len;
+ ushort ifid_pad;
+- int ifid_lbn;
+- int ifid_offset;
+ int ifid_ino;
+ };
+
+ int
+--- 495,505 ----
+ * - check that the generation number matches
+ */
+
+ struct ifid {
+ ushort ifid_len;
+ ushort ifid_pad;
+ int ifid_ino;
++ off_t ifid_start;
+ };
+
+ int
+***************
+*** 502,563 ****
+ struct buf *bp;
+ struct iso_directory_record *dirp;
+ struct iso_node *ip, *nip;
+! struct proc *p;
+!
+ ifhp = (struct ifid *)fhp;
+ imp = VFSTOISOFS (mp);
+!
+ #ifdef ISOFS_DBG
+! printf("fhtovp: lbn %d, off %d, ino %d\n",
+! ifhp->ifid_lbn, ifhp->ifid_offset, ifhp->ifid_ino);
+ #endif
+!
+! lbn = ifhp->ifid_lbn;
+! off = ifhp->ifid_offset;
+! ifhp->ifid_lbn += (ifhp->ifid_offset >> 11);
+! ifhp->ifid_offset &= 0x7ff;
+!
+! if (ifhp->ifid_lbn >= imp->volume_space_size)
+! return (EINVAL);
+!
+! if (ifhp->ifid_offset + sizeof (struct iso_directory_record)
+! > imp->im_bsize)
+! return (EINVAL);
+!
+! if (error = bread (imp->im_devvp,
+! (ifhp->ifid_lbn * imp->im_bsize / DEV_BSIZE), imp->im_bsize,
+! NOCRED, &bp)) {
+! printf("fhtovp: bread error %d\n", error);
+! return(EINVAL);
+ }
+!
+! dirp = (struct iso_directory_record *)
+! (bp->b_un.b_addr + ifhp->ifid_offset);
+!
+! if (ifhp->ifid_offset + isonum_711 (dirp->length) > imp->im_bsize) {
+! brelse (bp);
+! return (EINVAL);
+ }
+! if (isonum_733(dirp->extent) != ifhp->ifid_ino) {
+ brelse(bp);
+! return(EINVAL);
+ }
+!
+ tvp.v_mount = mp;
+ ip = VTOI(&tvp);
+ ip->i_vnode = &tvp;
+ ip->i_dev = imp->im_dev;
+! ip->i_diroff = off;
+! ip->iso_extent = lbn;
+! if (error = iso_iget(ip, ifhp->ifid_ino, &nip, dirp)) {
+ *vpp = NULLVP;
+! brelse (bp);
+! return (error);
+ }
+ ip = nip;
+ *vpp = ITOV(ip);
+! brelse (bp);
+! return (0);
+ }
+
+ /*
+--- 517,585 ----
+ struct buf *bp;
+ struct iso_directory_record *dirp;
+ struct iso_node *ip, *nip;
+!
+ ifhp = (struct ifid *)fhp;
+ imp = VFSTOISOFS (mp);
+!
+ #ifdef ISOFS_DBG
+! printf("fhtovp: ino %d, start %ld\n",ifhp->ifid_ino,ifhp->ifid_start);
+ #endif
+!
+! lbn = ifhp->ifid_ino >> imp->im_bshift;
+! off = ifhp->ifid_ino & imp->im_bmask;
+!
+! if (lbn >= imp->volume_space_size) {
+! printf("fhtovp: lbn exceed volume space %d\n",lbn);
+! return EINVAL;
+ }
+!
+! if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
+! printf("fhtovp: across the block boundary %d\n",
+! off + ISO_DIRECTORY_RECORD_SIZE);
+! return EINVAL;
+ }
+!
+! if (error = bread(imp->im_devvp,
+! lbn * imp->logical_block_size / DEV_BSIZE,
+! imp->logical_block_size,
+! NOCRED,&bp)) {
+! printf("fhtovp: bread error %d\n",error);
+ brelse(bp);
+! return EINVAL;
+ }
+!
+! dirp = (struct iso_directory_record *)(bp->b_un.b_addr + off);
+!
+! if (off + isonum_711(dirp->length) > imp->logical_block_size) {
+! brelse(bp);
+! printf("fhtovp: directory across the block boundary %d[off=%d/len=%d]\n",
+! off + isonum_711(dirp->length),off,isonum_711(dirp->length));
+! return EINVAL;
+! }
+!
+! if (isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length)
+! != ifhp->ifid_start) {
+! brelse(bp);
+! printf("fhtovp: file start miss %d vs %d\n",
+! isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length),
+! ifhp->ifid_start);
+! return EINVAL;
+! }
+!
+ tvp.v_mount = mp;
+ ip = VTOI(&tvp);
+ ip->i_vnode = &tvp;
+ ip->i_dev = imp->im_dev;
+! if (error = iso_iget(ip,ifhp->ifid_ino,0,&nip,dirp)) {
+ *vpp = NULLVP;
+! brelse(bp);
+! printf("fhtovp: failed to get ino\n");
+! return error;
+ }
+ ip = nip;
+ *vpp = ITOV(ip);
+! brelse(bp);
+! return 0;
+ }
+
+ /*
+***************
+*** 572,593 ****
+ register struct iso_node *ip = VTOI(vp);
+ register struct ifid *ifhp;
+ register struct iso_mnt *mp = ip->i_mnt;
+!
+ ifhp = (struct ifid *)fhp;
+ ifhp->ifid_len = sizeof(struct ifid);
+!
+! ifhp->ifid_lbn = ip->iso_parent_ext;
+! ifhp->ifid_offset = ip->iso_parent;
+ ifhp->ifid_ino = ip->i_number;
+!
+! if(ip->i_number == mp->root_extent) {
+! ifhp->ifid_lbn = ip->i_number;
+! ifhp->ifid_offset = 0;
+! }
+!
+ #ifdef ISOFS_DBG
+! printf("vptofh: lbn %d, off %d, ino %d\n",
+! ifhp->ifid_lbn, ifhp->ifid_offset, ifhp->ifid_ino);
+ #endif
+! return (0);
+ }
+--- 594,609 ----
+ register struct iso_node *ip = VTOI(vp);
+ register struct ifid *ifhp;
+ register struct iso_mnt *mp = ip->i_mnt;
+!
+ 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;
+ }
+diff -cr sys/isofs/isofs_vnops.c src/sys/isofs/isofs_vnops.c
+*** sys/isofs/isofs_vnops.c Sun Jun 12 05:05:29 1994
+--- src/sys/isofs/isofs_vnops.c Mon Aug 15 15:43:52 1994
+***************
+*** 1,26 ****
+ /*
+ * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk 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 "isofs_node.h"
+! #include "iso_rrip.h"
+
+ /*
+ * Open called.
+--- 1,84 ----
+ /*
+ * patch013,v 1.1.1.1 1994/09/01 23:28:29 phk Exp
+ */
+!
+! #include <sys/param.h>
+! #include <sys/systm.h>
+! #include <sys/namei.h>
+! #include <sys/resourcevar.h>
+! #include <sys/kernel.h>
+! #include <sys/file.h>
+! #include <sys/stat.h>
+! #include <sys/buf.h>
+! #include <sys/proc.h>
+! #include <sys/conf.h>
+! #include <sys/mount.h>
+! #include <sys/vnode.h>
+! #include <sys/malloc.h>
+! #include <sys/dir.h>
+!
+! #include <sys/specdev.h> /* XXX */
+! #include <sys/fifo.h> /* XXX */
+!
+! #include <isofs/iso.h>
+! #include <isofs/isofs_node.h>
+! #include <isofs/iso_rrip.h>
+!
+! /*
+! * Mknod vnode call
+! * Actually remap the device number
+! */
+! /* ARGSUSED */
+! int
+! isofs_mknod(ndp, vap, cred, p)
+! struct nameidata *ndp;
+! struct ucred *cred;
+! struct vattr *vap;
+! struct proc *p;
+! {
+! #ifndef ISODEVMAP
+! free(ndp->ni_pnbuf, M_NAMEI);
+! vput(ndp->ni_dvp);
+! vput(ndp->ni_vp);
+! return EINVAL;
+! #else
+! register struct vnode *vp;
+! struct iso_node *ip;
+! struct iso_dnode *dp;
+! int error;
+!
+! vp = ndp->ni_vp;
+! ip = VTOI(vp);
+!
+! if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP
+! || vap->va_type != vp->v_type
+! || (vap->va_type != VCHR && vap->va_type != VBLK)) {
+! free(ndp->ni_pnbuf, M_NAMEI);
+! vput(ndp->ni_dvp);
+! vput(ndp->ni_vp);
+! return EINVAL;
+! }
+!
+! dp = iso_dmap(ip->i_dev,ip->i_number,1);
+! if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) {
+! /* same as the unmapped one, delete the mapping */
+! remque(dp);
+! FREE(dp,M_CACHE);
+! } else
+! /* enter new mapping */
+! dp->d_dev = vap->va_rdev;
+!
+! /*
+! * Remove inode so that it will be reloaded by iget and
+! * checked to see if it is an alias of an existing entry
+! * in the inode cache.
+! */
+! vput(vp);
+! vp->v_type = VNON;
+! vgone(vp);
+! return (0);
+! #endif
+! }
+
+ /*
+ * Open called.
+***************
+*** 66,72 ****
+ struct ucred *cred;
+ struct proc *p;
+ {
+! return (0);
+ }
+
+ /* ARGSUSED */
+--- 124,146 ----
+ struct ucred *cred;
+ struct proc *p;
+ {
+! register struct iso_node *ip = VTOI(vp);
+! register gid_t *gp;
+! int i;
+!
+! if (cred->cr_uid == 0)
+! return 0;
+! if (cred->cr_uid != ip->inode.iso_uid) {
+! mode >>= 3;
+! gp = cred->cr_groups;
+! for (i = 0; i < cred->cr_ngroups; i++, gp++)
+! if (ip->inode.iso_gid == *gp)
+! goto found;
+! mode >>= 3;
+! found:
+! ;
+! }
+! return (ip->inode.iso_mode & mode) == mode ? 0 : EACCES;
+ }
+
+ /* ARGSUSED */
+***************
+*** 82,109 ****
+
+ vap->va_fsid = ip->i_dev;
+ vap->va_fileid = ip->i_number;
+- /*
+- * This should be set properly if a RR filesystem, but this is
+- * the safest value for now. Note that previously this was conditionally
+- * set to 2 if the file is a directory, but this causes problems
+- * with find.
+- */
+- vap->va_nlink = 1;
+
+! vap->va_mode = ip->inode.iso_mode;
+! 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 = 0;
+! vap->va_size = ip->i_size;
+ vap->va_size_rsv = 0;
+! vap->va_flags = 0;
+ vap->va_gen = 1;
+ vap->va_blocksize = ip->i_mnt->logical_block_size;
+! vap->va_bytes = ip->i_size;
+ vap->va_bytes_rsv = 0;
+ vap->va_type = vp->v_type;
+ return (0);
+--- 156,178 ----
+
+ vap->va_fsid = ip->i_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 = ip->i_size;
+ vap->va_size_rsv = 0;
+! vap->va_flags = 0;
+ vap->va_gen = 1;
+ vap->va_blocksize = ip->i_mnt->logical_block_size;
+! vap->va_bytes = ip->i_size;
+ vap->va_bytes_rsv = 0;
+ vap->va_type = vp->v_type;
+ return (0);
+***************
+*** 126,139 ****
+ daddr_t lbn, bn, rablock;
+ int size, diff, error = 0;
+ long n, on, type;
+!
+! #ifdef DIAGNOSTICx
+! if (uio->uio_rw != UIO_READ)
+! panic("isofs_read mode");
+! type = ip->i_mode & IFMT;
+! if (type != IFDIR && type != IFREG && type != IFLNK)
+! panic("isofs_read type");
+! #endif
+ if (uio->uio_resid == 0)
+ return (0);
+ if (uio->uio_offset < 0)
+--- 195,201 ----
+ daddr_t lbn, bn, rablock;
+ int size, diff, error = 0;
+ long n, on, type;
+!
+ if (uio->uio_resid == 0)
+ return (0);
+ if (uio->uio_offset < 0)
+***************
+*** 143,149 ****
+ do {
+ lbn = iso_lblkno(imp, uio->uio_offset);
+ on = iso_blkoff(imp, uio->uio_offset);
+! n = MIN((unsigned)(imp->im_bsize - on), uio->uio_resid);
+ diff = ip->i_size - uio->uio_offset;
+ if (diff <= 0)
+ return (0);
+--- 205,211 ----
+ do {
+ lbn = iso_lblkno(imp, uio->uio_offset);
+ on = iso_blkoff(imp, uio->uio_offset);
+! n = min((unsigned)(imp->logical_block_size - on), uio->uio_resid);
+ diff = ip->i_size - uio->uio_offset;
+ if (diff <= 0)
+ return (0);
+***************
+*** 180,185 ****
+--- 242,248 ----
+ struct ucred *cred;
+ struct proc *p;
+ {
++ printf("You did ioctl for isofs !!\n");
+ return (ENOTTY);
+ }
+
+***************
+*** 232,237 ****
+--- 295,386 ----
+ }
+
+ /*
++ * 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 eof;
++ };
++
++ 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 = DIRSIZ(dp);
++
++ if (idp->uio->uio_resid < dp->d_reclen) {
++ idp->eof = 0;
++ return -1;
++ }
++
++ if (error = uiomove(dp,dp->d_reclen,idp->uio))
++ 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;
++ if (assoc = cl > 1 && *cname == ASSOCCHAR) {
++ 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))
++ return error;
++ idp->assocent.d_namlen = 0;
++ }
++ if (idp->saveent.d_namlen) {
++ if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
++ return error;
++ idp->saveent.d_namlen = 0;
++ }
++ }
++ }
++ idp->current.d_reclen = 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
+ */
+ int
+***************
+*** 241,248 ****
+ struct ucred *cred;
+ int *eofflagp;
+ {
+! struct dirent dirent;
+! int iso_offset;
+ int entryoffsetinblock;
+ int error = 0;
+ int endsearch;
+--- 390,396 ----
+ struct ucred *cred;
+ int *eofflagp;
+ {
+! struct isoreaddir *idp;
+ int entryoffsetinblock;
+ int error = 0;
+ int endsearch;
+***************
+*** 251,460 ****
+ struct iso_mnt *imp;
+ struct iso_node *ip;
+ struct buf *bp = NULL;
+! int i;
+! int end_flag = 0;
+! ISO_RRIP_ANALYZE ana;
+!
+ ip = VTOI (vp);
+ imp = ip->i_mnt;
+!
+! iso_offset = uio->uio_offset;
+!
+! entryoffsetinblock = iso_blkoff(imp, iso_offset);
+ if (entryoffsetinblock != 0) {
+! if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp))
+ return (error);
+ }
+!
+ endsearch = ip->i_size;
+!
+! while (iso_offset < endsearch && uio->uio_resid > 0) {
+ /*
+ * If offset is on a block boundary,
+ * read the next directory block.
+ * Release previous if it exists.
+ */
+!
+! if (iso_blkoff(imp, iso_offset) == 0) {
+ if (bp != NULL)
+ brelse(bp);
+! if (error = iso_blkatoff(ip, iso_offset,
+! (char **)0, &bp))
+! return (error);
+ entryoffsetinblock = 0;
+ }
+ /*
+ * Get pointer to next entry.
+ */
+!
+ ep = (struct iso_directory_record *)
+ (bp->b_un.b_addr + entryoffsetinblock);
+!
+ reclen = isonum_711 (ep->length);
+ if (reclen == 0) {
+ /* skip to next block, if any */
+! iso_offset = roundup (iso_offset,
+! imp->logical_block_size);
+ continue;
+ }
+!
+! if (reclen < sizeof (struct iso_directory_record))
+ /* illegal entry, stop */
+ break;
+!
+! /* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size)
+ /* 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)
+ /* illegal entry, stop */
+ break;
+!
+ /*
+ *
+ */
+! switch (ep->name[0]) {
+! case 0:
+! dirent.d_name[0] = '.';
+! dirent.d_namlen = 1;
+! break;
+! case 1:
+! dirent.d_name[0] = '.';
+! dirent.d_name[1] = '.';
+! dirent.d_namlen = 2;
+ break;
+! default:
+! switch ( imp->iso_ftype ) {
+! case ISO_FTYPE_RRIP:
+! isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen );
+ break;
+! case ISO_FTYPE_9660:
+! {
+! int namelen = dirent.d_namlen;
+! isofntrans(ep->name, dirent.d_namlen,
+! dirent.d_name, &namelen);
+! dirent.d_namlen = namelen;
+ break;
+- }
+ default:
+ break;
+ }
+- break;
+ }
+!
+! dirent.d_name[dirent.d_namlen] = 0;
+! dirent.d_reclen = DIRSIZ (&dirent);
+!
+! if (uio->uio_resid < dirent.d_reclen)
+! break;
+!
+! if (error = uiomove (&dirent, dirent.d_reclen, uio))
+ break;
+!
+! iso_offset += reclen;
+ entryoffsetinblock += reclen;
+ }
+!
+ if (bp)
+ brelse (bp);
+
+! if (end_flag || (VTOI(vp)->i_size - iso_offset) <= 0)
+! *eofflagp = 1;
+! else
+! *eofflagp = 0;
+!
+! uio->uio_offset = iso_offset;
+!
+ return (error);
+ }
+
+ /*
+ * Return target name of a symbolic link
+ */
+ typedef struct iso_directory_record ISODIR;
+ typedef struct iso_node ISONODE;
+ typedef struct iso_mnt ISOMNT;
+ int isofs_readlink(vp, uio, cred)
+! struct vnode *vp;
+! struct uio *uio;
+! struct ucred *cred;
+! {
+! ISONODE *ip;
+! ISODIR *dirp;
+! ISOMNT *imp;
+! struct buf *bp;
+! int symlen;
+! int error;
+! char symname[NAME_MAX];
+!
+! ip = VTOI( vp );
+! imp = ip->i_mnt;
+! /*
+! * Get parents directory record block that this inode included.
+! */
+! error = bread( imp->im_devvp,
+! (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 11 ) )
+! * imp->im_bsize / DEV_BSIZE ),
+! imp->im_bsize,
+! NOCRED,
+! &bp );
+! if ( error ) {
+! return( EINVAL );
+! }
+!
+! /*
+! * Setup the directory pointer for this inode
+! */
+
+! dirp = (ISODIR *)(bp->b_un.b_addr + ( ip->iso_parent & 0x7ff ) );
+ #ifdef DEBUG
+! printf("lbn=%d[base=%d,off=%d,bsize=%d,DEV_BSIZE=%d], dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n",
+! (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 12 ) ) * imp->im_bsize / DEV_BSIZE ),
+! ip->iso_parent_ext,
+! (ip->iso_parent >> 11 ),
+! imp->im_bsize,
+! DEV_BSIZE,
+! dirp,
+! bp->b_un.b_addr,
+! ip->iso_parent,
+! ip->iso_parent & 0x7ff );
+ #endif
+!
+! /*
+! * Just make sure, we have a right one....
+! * 1: Check not cross boundary on block
+! * 2: Check number of inode
+! */
+! if ( (ip->iso_parent & 0x7ff) + isonum_711( dirp->length ) >=
+! imp->im_bsize ) {
+! brelse ( bp );
+! return( EINVAL );
+! }
+! if ( isonum_733(dirp->extent) != ip->i_number ) {
+! brelse ( bp );
+! return( EINVAL );
+! }
+!
+! /*
+! * Ok, we just gathering a Symbolick name in SL record.
+! */
+! if ( isofs_rrip_getsymname( vp, dirp, symname, &symlen ) == 0 ) {
+! brelse ( bp );
+! return( EINVAL );
+! }
+! /*
+! * Don't forget before you leave from home ;-)
+! */
+! brelse( bp );
+!
+! /*
+! * return with the Symbolick name to caller's.
+! */
+! return ( uiomove( symname, symlen, uio ) );
+ }
+
+ /*
+--- 399,632 ----
+ struct iso_mnt *imp;
+ struct iso_node *ip;
+ struct buf *bp = NULL;
+!
+ ip = VTOI (vp);
+ imp = ip->i_mnt;
+!
+! MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK);
+! idp->saveent.d_namlen = 0;
+! idp->assocent.d_namlen = 0;
+! idp->uio = uio;
+! idp->curroff = uio->uio_offset;
+! idp->eof = 1;
+!
+! entryoffsetinblock = iso_blkoff(imp, idp->curroff);
+ if (entryoffsetinblock != 0) {
+! if (error = iso_blkatoff(ip, idp->curroff, &bp)) {
+! FREE(idp,M_TEMP);
+ return (error);
++ }
+ }
+!
+ endsearch = ip->i_size;
+!
+! while (idp->curroff < endsearch) {
+ /*
+ * If offset is on a block boundary,
+ * read the next directory block.
+ * Release previous if it exists.
+ */
+!
+! if (iso_blkoff(imp, idp->curroff) == 0) {
+ if (bp != NULL)
+ brelse(bp);
+! if (error = iso_blkatoff(ip, idp->curroff, &bp))
+! break;
+ entryoffsetinblock = 0;
+ }
+ /*
+ * Get pointer to next entry.
+ */
+!
+ ep = (struct iso_directory_record *)
+ (bp->b_un.b_addr + entryoffsetinblock);
+!
+ reclen = isonum_711 (ep->length);
+ if (reclen == 0) {
+ /* skip to next block, if any */
+! idp->curroff = roundup (idp->curroff,
+! 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 (isonum_711(ep->flags)&2)
+! isodirino(&idp->current.d_fileno,ep,imp);
+! else
+! idp->current.d_fileno = (bp->b_blkno << DEV_BSHIFT) + idp->curroff;
+!
+! if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
+! error = EINVAL;
+ /* illegal entry, stop */
+ break;
+! }
+!
+! idp->curroff += reclen;
+ /*
+ *
+ */
+! switch (imp->iso_ftype) {
+! case ISO_FTYPE_RRIP:
+! isofs_rrip_getname(ep,idp->current.d_name,
+! &idp->current.d_namlen,
+! &idp->current.d_fileno,imp);
+! if (idp->current.d_namlen)
+! error = iso_uiodir(idp,&idp->current,idp->curroff);
+ break;
+! default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
+! strcpy(idp->current.d_name,"..");
+! switch (ep->name[0]) {
+! case 0:
+! idp->current.d_namlen = 1;
+! error = iso_uiodir(idp,&idp->current,idp->curroff);
+ break;
+! case 1:
+! idp->current.d_namlen = 2;
+! error = iso_uiodir(idp,&idp->current,idp->curroff);
+ break;
+ default:
++ isofntrans(ep->name,idp->current.d_namlen,
++ idp->current.d_name,&idp->current.d_namlen,
++ imp->iso_ftype == ISO_FTYPE_9660,
++ isonum_711(ep->flags)&4);
++ if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
++ error = iso_shipdir(idp);
++ else
++ error = iso_uiodir(idp,&idp->current,idp->curroff);
+ break;
+ }
+ }
+! if (error)
+ break;
+!
+ entryoffsetinblock += reclen;
+ }
+!
+! if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
+! idp->current.d_namlen = 0;
+! error = iso_shipdir(idp);
+! }
+! if (error < 0)
+! error = 0;
+!
+ if (bp)
+ brelse (bp);
+
+! uio->uio_offset = idp->uio_off;
+! *eofflagp = idp->eof;
+!
+! 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 isofs_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;
+ int isofs_readlink(vp, uio, cred)
+! struct vnode *vp;
+! struct uio *uio;
+! struct ucred *cred;
+! {
+! ISONODE *ip;
+! ISODIR *dirp;
+! ISOMNT *imp;
+! struct buf *bp;
+! u_short symlen;
+! int error;
+! char *symname;
+! ino_t ino;
+!
+! ip = VTOI(vp);
+! imp = ip->i_mnt;
+!
+! if (imp->iso_ftype != ISO_FTYPE_RRIP)
+! return EINVAL;
+!
+! /*
+! * Get parents directory record block that this inode included.
+! */
+! error = bread(imp->im_devvp,
+! (daddr_t)((ip->i_number&~imp->im_bmask) / DEV_BSIZE),
+! imp->logical_block_size,
+! NOCRED,
+! &bp);
+! if (error) {
+! brelse(bp);
+! return EINVAL;
+! }
+
+! /*
+! * Setup the directory pointer for this inode
+! */
+! dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask));
+ #ifdef DEBUG
+! printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n",
+! (daddr_t)(ip->i_number >> imp->im_bshift),
+! ip->i_number & imp->im_bmask,
+! imp->logical_block_size,
+! DEV_BSIZE,
+! dirp,
+! bp->b_un.b_addr,
+! ip->i_number,
+! ip->i_number & imp->im_bmask );
+ #endif
+!
+! /*
+! * 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)
+! > imp->logical_block_size) {
+! brelse(bp);
+! return EINVAL;
+! }
+!
+! /*
+! * Now get a buffer
+! * Abuse a namei buffer for now.
+! */
+! MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK);
+!
+! /*
+! * Ok, we just gathering a symbolic name in SL record.
+! */
+! if (isofs_rrip_getsymname(dirp,symname,&symlen,imp) == 0) {
+! FREE(symname,M_NAMEI);
+! brelse(bp);
+! return EINVAL;
+! }
+! /*
+! * Don't forget before you leave from home ;-)
+! */
+! brelse(bp);
+!
+! /*
+! * return with the symbolic name to caller's.
+! */
+! error = uiomove(symname,symlen,uio);
+!
+! FREE(symname,M_NAMEI);
+!
+! return error;
+ }
+
+ /*
+***************
+*** 469,475 ****
+
+ if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
+ FREE(ndp->ni_pnbuf, M_NAMEI);
+! return (0);
+ }
+
+ /*
+--- 641,647 ----
+
+ if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
+ FREE(ndp->ni_pnbuf, M_NAMEI);
+! return 0;
+ }
+
+ /*
+***************
+*** 482,488 ****
+ register struct iso_node *ip = VTOI(vp);
+
+ ISO_ILOCK(ip);
+! return (0);
+ }
+
+ /*
+--- 654,660 ----
+ register struct iso_node *ip = VTOI(vp);
+
+ ISO_ILOCK(ip);
+! return 0;
+ }
+
+ /*
+***************
+*** 497,503 ****
+ if (!(ip->i_flag & ILOCKED))
+ panic("isofs_unlock NOT LOCKED");
+ ISO_IUNLOCK(ip);
+! return (0);
+ }
+
+ /*
+--- 669,675 ----
+ if (!(ip->i_flag & ILOCKED))
+ panic("isofs_unlock NOT LOCKED");
+ ISO_IUNLOCK(ip);
+! return 0;
+ }
+
+ /*
+***************
+*** 509,516 ****
+ {
+
+ if (VTOI(vp)->i_flag & ILOCKED)
+! return (1);
+! return (0);
+ }
+
+ /*
+--- 681,688 ----
+ {
+
+ if (VTOI(vp)->i_flag & ILOCKED)
+! return 1;
+! return 0;
+ }
+
+ /*
+***************
+*** 530,547 ****
+ panic("isofs_strategy: spec");
+ if (bp->b_blkno == bp->b_lblkno) {
+ if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno))
+! return (error);
+ if ((long)bp->b_blkno == -1)
+ clrbuf(bp);
+ }
+ if ((long)bp->b_blkno == -1) {
+ biodone(bp);
+! return (0);
+ }
+ vp = ip->i_devvp;
+ bp->b_dev = vp->v_rdev;
+ (*(vp->v_op->vop_strategy))(bp);
+! return (0);
+ }
+
+ /*
+--- 702,719 ----
+ panic("isofs_strategy: spec");
+ if (bp->b_blkno == bp->b_lblkno) {
+ if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno))
+! return error;
+ if ((long)bp->b_blkno == -1)
+ clrbuf(bp);
+ }
+ if ((long)bp->b_blkno == -1) {
+ biodone(bp);
+! return 0;
+ }
+ vp = ip->i_devvp;
+ bp->b_dev = vp->v_rdev;
+ (*(vp->v_op->vop_strategy))(bp);
+! return 0;
+ }
+
+ /*
+***************
+*** 551,557 ****
+ isofs_print(vp)
+ struct vnode *vp;
+ {
+! printf ("tag VT_ISOFS, isofs vnode\n");
+ }
+
+ extern int enodev ();
+--- 723,729 ----
+ isofs_print(vp)
+ struct vnode *vp;
+ {
+! printf("tag VT_ISOFS, isofs vnode\n");
+ }
+
+ extern int enodev ();
+***************
+*** 594,596 ****
+--- 766,842 ----
+ isofs_islocked, /* islocked */
+ (void *)enodev, /* advlock */
+ };
++
++ struct vnodeops isofs_spec_inodeops = {
++ spec_lookup, /* lookup */
++ (void *)enodev, /* create */
++ (void *)enodev, /* mknod */
++ spec_open, /* open */
++ spec_close, /* close */
++ isofs_access, /* access */
++ isofs_getattr, /* getattr */
++ (void *)enodev, /* setattr */
++ spec_read, /* read */
++ spec_write, /* write */
++ spec_ioctl, /* ioctl */
++ spec_select, /* select */
++ spec_mmap, /* mmap */
++ spec_fsync, /* fsync */
++ spec_seek, /* seek */
++ (void *)enodev, /* remove */
++ (void *)enodev, /* link */
++ (void *)enodev, /* rename */
++ (void *)enodev, /* mkdir */
++ (void *)enodev, /* rmdir */
++ (void *)enodev, /* symlink */
++ spec_readdir, /* readdir */
++ spec_readlink, /* readlink */
++ spec_abortop, /* abortop */
++ isofs_inactive, /* inactive */
++ isofs_reclaim, /* reclaim */
++ isofs_lock, /* lock */
++ isofs_unlock, /* unlock */
++ (void *)enodev, /* bmap */
++ spec_strategy, /* strategy */
++ isofs_print, /* print */
++ isofs_islocked, /* islocked */
++ spec_advlock, /* advlock */
++ };
++
++ #ifdef FIFO
++ struct vnodeops isofs_fifo_inodeops = {
++ fifo_lookup, /* lookup */
++ (void *)enodev, /* create */
++ (void *)enodev, /* mknod */
++ fifo_open, /* open */
++ fifo_close, /* close */
++ isofs_access, /* access */
++ isofs_getattr, /* getattr */
++ (void *)enodev, /* setattr */
++ fifo_read, /* read */
++ fifo_write, /* write */
++ fifo_ioctl, /* ioctl */
++ fifo_select, /* select */
++ fifo_mmap, /* mmap */
++ fifo_fsync, /* fsync */
++ fifo_seek, /* seek */
++ (void *)enodev, /* remove */
++ (void *)enodev, /* link */
++ (void *)enodev, /* rename */
++ (void *)enodev, /* mkdir */
++ (void *)enodev, /* rmdir */
++ (void *)enodev, /* symlink */
++ fifo_readdir, /* readdir */
++ fifo_readlink, /* readlink */
++ fifo_abortop, /* abortop */
++ isofs_inactive, /* inactive */
++ isofs_reclaim, /* reclaim */
++ isofs_lock, /* lock */
++ isofs_unlock, /* unlock */
++ (void *)enodev, /* bmap */
++ fifo_strategy, /* strategy */
++ isofs_print, /* print */
++ isofs_islocked, /* islocked */
++ fifo_advlock, /* advlock */
++ };
++ #endif /* FIFO */
+diff -cr sys/sys/mount.h src/sys/sys/mount.h
+*** sys/sys/mount.h Mon Mar 7 11:39:02 1994
+--- src/sys/sys/mount.h Mon Aug 15 15:47:20 1994
+***************
+*** 286,291 ****
+--- 286,306 ----
+ };
+ #endif /* PCFS */
+
++ #ifdef ISOFS
++ /*
++ * Arguments to mount ISO 9660 filesystems.
++ */
++ struct iso_args {
++ char *fspec; /* block special holding the fs to mount */
++ int flags; /* mounting flags, see below */
++ uid_t exroot; /* mapping for root uid */
++ };
++ #define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
++ #define ISOFSMNT_GENS 0x00000002 /* enable usage of generation numbers */
++ #define ISOFSMNT_EXTATT 0x00000004 /* enable usage of extended attributes */
++ #endif /* ISOFS */
++
++
+ #ifdef KERNEL
+ /*
+ * exported vnode operations
+--
+Doug Rabson, RenderMorphics Ltd. Mail: dfr@render.com
+ Phone: +44 71 251 4411
+ FAX: +44 71 251 0939