From owner-freebsd-multimedia Sun Apr 26 10:23:18 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id KAA21736 for freebsd-multimedia-outgoing; Sun, 26 Apr 1998 10:19:48 -0700 (PDT) (envelope-from owner-freebsd-multimedia@FreeBSD.ORG) Received: from server.local.sunyit.edu (A-T34.rh.sunyit.edu [150.156.210.241]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA21372 for ; Sun, 26 Apr 1998 10:14:57 -0700 (PDT) (envelope-from perlsta@cs.sunyit.edu) Received: from localhost (perlsta@localhost) by server.local.sunyit.edu (8.8.8/8.8.5) with SMTP id NAA27009 for ; Sun, 26 Apr 1998 13:07:39 -0500 (EST) X-Authentication-Warning: server.local.sunyit.edu: perlsta owned process doing -bs Date: Sun, 26 Apr 1998 13:07:38 -0500 (EST) From: Alfred Perlstein X-Sender: perlsta@server.local.sunyit.edu To: multimedia@FreeBSD.ORG Subject: can someone please commit the joliet patches. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-multimedia@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org if someone has a few spare minutes could they please commit PR kern/5038? it's patches to add joliet to cd9660 support. thank you, -Alfred PR-follows, didn't know whether this would annoy or help the person doing the patch so they don't have to web around looking for it, sorry if this annoys anyone. Problem Report kern/5038 FreeBSD can't read MS Joliet CDs. Confidential no Severity non-critical Priority high Responsible freebsd-bugs@freebsd.org State open Class change-request Submitter-Id current-users Arrival-Date Fri Nov 14 00:20:02 PST 1997 Last-Modified Wed Apr 1 21:35:49 PST 1998 Originator Keith Jang keith@email.gcn.net.tw Organization private site Release FreeBSD 3.0-current Environment FreeBSD 3.0-CURRENT #36: Fri Nov 14 03:27:44 CST 1997 Description FreeBSD can't read the long filenames on Joliet CDs. How-To-Repeat Just insert a Joliet CD, and the filenames are changed to xxx~1. Fix I modified some code under /sys/isofs/cd9660, and it can read the long filenames, though Unicode is not implemented yet. Audit-Trail From: Keith Jang To: freebsd-gnats-submit@freebsd.org Cc: Subject: Re: kern/5038 Date: Sat, 15 Nov 1997 14:32:48 +0800 (CST) The following are three files with a patch for reading joliet. /sys/isofs/cd9660/cd9660_joliet.h: begin 644 cd9660_joliet.h.gz M'XL("`E9;#0``V-D.38V,%]J;VQI970N:`!U4FUKVS`8_.Y?<3`86_'RNI:$ M?NIB=Z1X-#0A7\8HBOPX%E,L(\EMPMA_WR,EA<(2,+*MTYWN3NI?);C"#R6M M<:;R>#!:D4>^]SUX@_GR<7IS,\`L@VM)JDI)X95IF-1/DGXDGRB=(X=EU[:: M=M1X80]8&]WM"!DY:57KC85P$`V$]F0;%GHAWB1H+*S:G67TL*H)"^%KK,1& M$S[BR1B/3%F2C!_P1-+8,HB8"LMUAHWAQ:U1C0\)!$I55639$@JS9?\:W[21 MO^%KMK)89RE>:R7KH*!-L^4=ND9)4Q(JI:D1.\YER:F2>F=BEU2IAE=L#IYX M5Z="/9B\F>'`]UIL78K)],MP-`@3N9.BC6*8GWH;1[X+K!,:;1GJ>4@W(3C68*F%])I MT!CLOP[2,([C>(V*SRK"&*88I>!Y9O(-"&>F#\3&,[5R$1[&VB_`X]IDD *_P"42;O1:`,``-;Z ` end /sys/isofs/cd9660/cd9660_joliet.c: begin 644 cd9660_joliet.c.gz M'XL("`E9;#0``V-D.38V,%]J;VQI970N8P"-4LMNFT`47<-77"52`O@)D5(U M)%[5E1Q9RJ)5-Y&%"(QC$IA!\W!B6?[W7@8H8!RK"WN8,^?3B=XZ8KVQ-"'R#`\O+9*94`D=:?!*)`TS8@G)522AX,<) M)Y%D?!?@R7@,#J((#DW#,`"B3Q-J$+\`BNA! M$G_"`TR'&LG"ST"CR$?4PNA49<$WU[6M,M-H5K_;OHF:*G@10M^QV"C?674- M%^/Q14E,UF!93CL(/*#(AJNK=A[+4D'9AMU+6`AE,#1O%+&"5"5IGH&820)%^!,-'N-5*OMM=\X M?]^QO'D8#&S8:W7E7+M0^[FFK4H/32-B5"94$;_2-'Z<$5[[URA]X21\[^CV MIE'.[[DR8%7MPJE`OFE8]88-!G6<@UG^X\&)5)S67OKFX=2NIV1+TO:F"Y7G M*TQ$Q),<-Q\YK\>LI>'Q:+N:_@\4/ M/?ZJJB.VVV=[=NV[^$ADM#F6>*MF+E&(7K74R_F?^=*]^]>QZP-TS#TI\!J! I]U^"FT9P #include + #include #include + #include /* * Convert a component of a pathname into a pointer to a locked inode. *************** *** 267,272 **** --- 269,287 ---- goto found; ino = 0; break; + case ISO_FTYPE_JOLIET: + if (isonum_711(ep->flags)&2) + ino = isodirino(ep, imp); + else + ino = dbtob(bp->b_blkno) + entryoffsetinblock; + + dp->i_ino = ino; + cd9660_joliet_getname(ep,altname,&namelen); + if (namelen == cnp->cn_namelen + && !bcmp(name, altname, namelen)) + goto found; + ino = 0; + break; } dp->i_offset += reclen; entryoffsetinblock += reclen; diff -c -r sys/isofs/cd9660/cd9660_mount.h sys.keith/isofs/cd9660/cd9660_mount.h *** sys/isofs/cd9660/cd9660_mount.h Thu Nov 13 03:26:37 1997 --- sys.keith/isofs/cd9660/cd9660_mount.h Fri Nov 14 22:03:43 1997 *************** *** 47,52 **** int flags; /* mounting flags, see below */ int ssector; /* starting sector, 0 for 1st session */ }; ! #define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/ ! #define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */ ! #define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */ --- 47,53 ---- int flags; /* mounting flags, see below */ int ssector; /* starting sector, 0 for 1st session */ }; ! #define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/ ! #define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */ ! #define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */ ! #define ISOFSMNT_NOJOLIET 0x00000008 /* disable Microsoft Joliet Ext.*/ diff -c -r sys/isofs/cd9660/cd9660_vfsops.c sys.keith/isofs/cd9660/cd9660_vfsops.c *** sys/isofs/cd9660/cd9660_vfsops.c Thu Nov 13 03:26:37 1997 --- sys.keith/isofs/cd9660/cd9660_vfsops.c Fri Nov 14 22:03:43 1997 *************** *** 55,61 **** --- 55,63 ---- #include #include + #include #include + #include #include #include *************** *** 261,267 **** struct iso_args *argp; { register struct iso_mnt *isomp = (struct iso_mnt *)0; ! struct buf *bp = NULL; dev_t dev = devvp->v_rdev; int error = EINVAL; int needclose = 0; --- 263,269 ---- struct iso_args *argp; { register struct iso_mnt *isomp = (struct iso_mnt *)0; ! struct buf *bp = NULL, *joliet_bp = NULL; dev_t dev = devvp->v_rdev; int error = EINVAL; int needclose = 0; *************** *** 271,279 **** --- 273,283 ---- int iso_blknum; struct iso_volume_descriptor *vdp = 0; struct iso_primary_descriptor *pri; + struct iso_supplementary_descriptor *sup = NULL; struct iso_sierra_primary_descriptor *pri_sierra; struct iso_directory_record *rootp; int logical_block_size; + int joliet_level = -1; if (!ronly) return EROFS; *************** *** 316,321 **** --- 320,344 ---- goto out; } else high_sierra = 1; + } else { + /* + * We know it's ISO9660 fs, now get Supplementary Volume + * Descriptor to check if it's Microsoft Joliet format. + */ + if (error = bread(devvp, (1 + iso_blknum) * btodb(iso_bsize), + iso_bsize, NOCRED, &joliet_bp)) + goto out; + + sup = (struct iso_supplementary_descriptor *)joliet_bp->b_data; + joliet_level = cd9660_joliet_level(sup); + + if (joliet_level < 0) { + argp->flags |= ISOFSMNT_NOJOLIET; + } else { + argp->flags |= ISOFSMNT_NORRIP; + argp->flags &= ~ISOFSMNT_GENS; + } + break; } if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) == ISO_VD_END) { *************** *** 328,340 **** brelse(bp); } ! if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) != ISO_VD_PRIMARY) { error = EINVAL; goto out; } - pri = (struct iso_primary_descriptor *)vdp; pri_sierra = (struct iso_sierra_primary_descriptor *)vdp; logical_block_size = isonum_723 (high_sierra? --- 351,363 ---- brelse(bp); } ! if ((isonum_711 (high_sierra? vdp->type_sierra: vdp->type) != ISO_VD_PRIMARY) && (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) != ISO_VD_SUPPLEMENTARY)) { error = EINVAL; goto out; } pri_sierra = (struct iso_sierra_primary_descriptor *)vdp; + pri = (struct iso_primary_descriptor *)vdp; logical_block_size = isonum_723 (high_sierra? *************** *** 350,356 **** rootp = (struct iso_directory_record *) (high_sierra? pri_sierra->root_directory_record: ! pri->root_directory_record); isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK); bzero((caddr_t)isomp, sizeof *isomp); --- 373,381 ---- rootp = (struct iso_directory_record *) (high_sierra? pri_sierra->root_directory_record: ! ((joliet_level < 0)? ! pri->root_directory_record: ! sup->root_directory_record)); isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK); bzero((caddr_t)isomp, sizeof *isomp); *************** *** 380,385 **** --- 405,412 ---- bp->b_flags |= B_AGE; brelse(bp); bp = NULL; + brelse(joliet_bp); + joliet_bp = NULL; mp->mnt_data = (qaddr_t)isomp; mp->mnt_stat.f_fsid.val[0] = (long)dev; *************** *** 416,439 **** brelse(bp); bp = NULL; } ! isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT); if(high_sierra) /* this effectively ignores all the mount flags */ isomp->iso_ftype = ISO_FTYPE_HIGH_SIERRA; else ! switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) { default: isomp->iso_ftype = ISO_FTYPE_DEFAULT; break; ! case ISOFSMNT_GENS|ISOFSMNT_NORRIP: isomp->iso_ftype = ISO_FTYPE_9660; break; ! case 0: isomp->iso_ftype = ISO_FTYPE_RRIP; break; } - return 0; out: if (bp) --- 443,469 ---- brelse(bp); bp = NULL; } ! isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT|ISOFSMNT_NOJOLIET); if(high_sierra) /* this effectively ignores all the mount flags */ isomp->iso_ftype = ISO_FTYPE_HIGH_SIERRA; else ! switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS| ! ISOFSMNT_NOJOLIET)) { default: isomp->iso_ftype = ISO_FTYPE_DEFAULT; break; ! case ISOFSMNT_GENS|ISOFSMNT_NORRIP|ISOFSMNT_NOJOLIET: isomp->iso_ftype = ISO_FTYPE_9660; break; ! case ISOFSMNT_NOJOLIET: isomp->iso_ftype = ISO_FTYPE_RRIP; break; + case ISOFSMNT_NORRIP: + isomp->iso_ftype = ISO_FTYPE_JOLIET; + break; } return 0; out: if (bp) *************** *** 507,513 **** struct iso_directory_record *dp = (struct iso_directory_record *)imp->root; ino_t ino = isodirino(dp, imp); ! /* * With RRIP we must use the `.' entry of the root directory. * Simply tell vget, that it's a relocated directory. --- 537,543 ---- struct iso_directory_record *dp = (struct iso_directory_record *)imp->root; ino_t ino = isodirino(dp, imp); ! /* * With RRIP we must use the `.' entry of the root directory. * Simply tell vget, that it's a relocated directory. diff -c -r sys/isofs/cd9660/cd9660_vnops.c sys.keith/isofs/cd9660/cd9660_vnops.c *** sys/isofs/cd9660/cd9660_vnops.c Thu Nov 13 03:26:37 1997 --- sys.keith/isofs/cd9660/cd9660_vnops.c Fri Nov 14 22:03:43 1997 *************** *** 56,61 **** --- 56,62 ---- #include #include #include + #include static int cd9660_setattr __P((struct vop_setattr_args *)); static int cd9660_access __P((struct vop_access_args *)); *************** *** 540,545 **** --- 541,552 ---- if (idp->current.d_namlen) error = iso_uiodir(idp,&idp->current,idp->curroff); break; + case ISO_FTYPE_JOLIET: + cd9660_joliet_getname(ep,idp->current.d_name, &namelen); + idp->current.d_namlen = (u_char)namelen; + if (idp->current.d_namlen) + error = iso_uiodir(idp,&idp->current,idp->curroff); + break; default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA*/ strcpy(idp->current.d_name,".."); switch (ep->name[0]) { diff -c -r sys/isofs/cd9660/iso.h sys.keith/isofs/cd9660/iso.h *** sys/isofs/cd9660/iso.h Thu Nov 13 03:26:37 1997 --- sys.keith/isofs/cd9660/iso.h Fri Nov 14 22:03:43 1997 *************** *** 54,59 **** --- 54,60 ---- /* volume descriptor types */ #define ISO_VD_PRIMARY 1 + #define ISO_VD_SUPPLEMENTARY 2 #define ISO_VD_END 255 #define ISO_STANDARD_ID "CD001" *************** *** 98,103 **** --- 99,145 ---- }; #define ISO_DEFAULT_BLOCK_SIZE 2048 + /* + * Used by Microsoft Joliet extension to ISO9660. Almost the same + * as PVD, but byte position 8 is a flag, and 89-120 is for escape. + */ + + struct iso_supplementary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char flags [ISODCL ( 8, 8)]; + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char escape [ISODCL ( 89, 120)]; + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; + }; + struct iso_sierra_primary_descriptor { char unknown1 [ISODCL ( 1, 8)]; /* 733 */ char type [ISODCL ( 9, 9)]; /* 711 */ *************** *** 175,181 **** /* CD-ROM Format type */ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ! ISO_FTYPE_ECMA, ISO_FTYPE_HIGH_SIERRA }; #ifndef ISOFSMNT_ROOT #define ISOFSMNT_ROOT 0 --- 217,223 ---- /* CD-ROM Format type */ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ! ISO_FTYPE_JOLIET, ISO_FTYPE_ECMA, ISO_FTYPE_HIGH_SIERRA }; #ifndef ISOFSMNT_ROOT #define ISOFSMNT_ROOT 0 Only in sys.keith/isofs/cd9660: iso_joliet.h From: Joachim Kuebart To: freebsd-gnats-submit@freebsd.org, keith@email.gcn.net.tw Cc: Subject: Re: kern/5038: FreeBSD can't read MS Joliet CDs. Date: Sun, 22 Mar 1998 19:47:44 +0100 (CET) Hi, this is a new diff from /usr/src to support Joliet FS extensions to CD9660. It will also run with RRIP, either like this or with minor modifications. I can do this as soon as someone supplies me with a documentation about mixing RRIP and Joliet (which is expressedly allowed in the Joliet documentation) or supplies me with a sample CD. This diff is to be used _instead_ of the diff in the original PR. This is expected to close PR bin/5567 when merged back to -stable. cu Jo --------------------------------------------------------------------- FreeBSD: The Power to Serve Joachim Kuebart Tel: +49 711 653706 Replicants are like any other machine -- Germany they're either a benefit or a hazard. Index: sbin/mount_cd9660/mount_cd9660.8 =================================================================== RCS file: /usr/CVS-Repository/src/sbin/mount_cd9660/mount_cd9660.8,v retrieving revision 1.5 diff -u -r1.5 mount_cd9660.8 --- mount_cd9660.8 1997/12/29 07:03:46 1.5 +++ mount_cd9660.8 1998/03/22 10:27:36 @@ -67,6 +67,8 @@ only the last one will be listed.) In either case, files may be opened without explicitly stating a version number. +.It Fl j +Do not use any Joliet extensions included in the filesystem. .It Fl o Options are specified with a .Fl o Index: sbin/mount_cd9660/mount_cd9660.c =================================================================== RCS file: /usr/CVS-Repository/src/sbin/mount_cd9660/mount_cd9660.c,v retrieving revision 1.12 diff -u -r1.12 mount_cd9660.c --- mount_cd9660.c 1997/04/29 15:56:40 1.12 +++ mount_cd9660.c 1998/03/16 18:41:59 @@ -73,6 +73,7 @@ { "extatt", 0, ISOFSMNT_EXTATT, 1 }, { "gens", 0, ISOFSMNT_GENS, 1 }, { "rrip", 1, ISOFSMNT_NORRIP, 1 }, + { "joliet", 1, ISOFSMNT_NOJOLIET, 1 }, { NULL } }; @@ -91,13 +92,16 @@ mntflags = opts = verbose = 0; memset(&args, 0, sizeof args); args.ssector = -1; - while ((ch = getopt(argc, argv, "ego:rs:v")) != -1) + while ((ch = getopt(argc, argv, "egjo:rs:v")) != -1) switch (ch) { case 'e': opts |= ISOFSMNT_EXTATT; break; case 'g': opts |= ISOFSMNT_GENS; + break; + case 'j': + opts |= ISOFSMNT_NOJOLIET; break; case 'o': getmntopts(optarg, mopts, &mntflags, &opts); Index: sys/isofs/cd9660/cd9660_lookup.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_lookup.c,v retrieving revision 1.20 diff -u -r1.20 cd9660_lookup.c --- cd9660_lookup.c 1997/11/07 08:52:50 1.20 +++ cd9660_lookup.c 1998/03/16 18:14:07 @@ -237,8 +237,7 @@ if (namelen != 1 || ep->name[0] != 0) goto notfound; - } else if (!(res = isofncmp(name,len, - ep->name,namelen))) { + } else if (!(res = isofncmp(name,len,ep->name,namelen,imp->joliet_level))) { if (isoflags & 2) ino = isodirino(ep, imp); else Index: sys/isofs/cd9660/cd9660_mount.h =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_mount.h,v retrieving revision 1.2 diff -u -r1.2 cd9660_mount.h --- cd9660_mount.h 1997/04/29 15:52:53 1.2 +++ cd9660_mount.h 1998/03/16 18:42:48 @@ -50,3 +50,4 @@ #define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/ #define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */ #define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */ +#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext. */ Index: sys/isofs/cd9660/cd9660_rrip.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_rrip.c,v retrieving revision 1.13 diff -u -r1.13 cd9660_rrip.c --- cd9660_rrip.c 1997/08/02 14:31:19 1.13 +++ cd9660_rrip.c 1998/03/22 18:05:34 @@ -298,18 +298,19 @@ struct iso_directory_record *isodir; ISO_RRIP_ANALYZE *ana; { - strcpy(ana->outbuf,".."); - switch (*isodir->name) { + isofntrans(isodir->name,isonum_711(isodir->name_len), + ana->outbuf,ana->outlen, + 1,isonum_711(isodir->flags)&4, + ana->imp->joliet_level); + switch (*ana->outbuf) { 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; + /* fall through */ + case 0: + /* outlen is 1 already */ + strcpy(ana->outbuf,".."); break; } } @@ -498,6 +499,7 @@ register ISO_SUSP_HEADER *pend; struct buf *bp = NULL; char *pwhead; + u_char c; int result; /* @@ -505,12 +507,11 @@ * it will be padding 1 byte after the name */ pwhead = isodir->name + isonum_711(isodir->name_len); - if (!(isonum_711(isodir->name_len)&1)) - pwhead++; + isochar(isodir->name, pwhead, ana->imp->joliet_level, &c); + pwhead += isonum_711(isodir->name_len) & 1; /* 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) + if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent) pwhead += ana->imp->rr_skip; else pwhead += ana->imp->rr_skip0; @@ -633,6 +634,7 @@ { ISO_RRIP_ANALYZE analyze; RRIP_TABLE *tab; + u_char c; analyze.outbuf = outbuf; analyze.outlen = outlen; @@ -642,9 +644,10 @@ analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; *outlen = 0; + isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), + imp->joliet_level, &c); tab = rrip_table_getname; - if (*isodir->name == 0 - || *isodir->name == 1) { + if (c == 0 || c == 1) { cd9660_rrip_defname(isodir,&analyze); analyze.fields &= ~ISO_SUSP_ALTNAME; Index: sys/isofs/cd9660/cd9660_util.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_util.c,v retrieving revision 1.10 diff -u -r1.10 cd9660_util.c --- cd9660_util.c 1997/04/10 14:35:11 1.10 +++ cd9660_util.c 1998/03/17 09:52:35 @@ -5,7 +5,8 @@ * This code is derived from software contributed to Berkeley * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension * Support code is derived from software contributed to Berkeley - * by Atsushi Murai (amurai@spec.co.jp). + * by Atsushi Murai (amurai@spec.co.jp). Joliet support was added by + * Joachim Kuebart (joki@kuebart.stuttgart.netsurf.de). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,37 +47,63 @@ #include /* + * Get one character out of an iso filename + * Obey joliet_level + * Return number of bytes consumed + */ +int +isochar(isofn, isoend, joliet_level, c) + u_char *isofn; + u_char *isoend; + int joliet_level; + u_char *c; +{ + *c = *isofn++; + if (joliet_level == 0 || isofn == isoend) + /* (00) and (01) are one byte in Joliet, too */ + return 1; + + /* No Unicode support yet :-( */ + switch (*c) { + default: + *c = '?'; + break; + case '\0': + *c = *isofn; + break; + } + return 2; +} + +/* * translate and compare a filename + * returns (fn - isofn) * Note: Version number plus ';' may be omitted. */ int -isofncmp(fn, fnlen, isofn, isolen) +isofncmp(fn, fnlen, isofn, isolen, joliet_level) u_char *fn; int fnlen; u_char *isofn; int isolen; + int joliet_level; { int i, j; - unsigned char c; + u_char c, *fnend = fn + fnlen, *isoend = isofn + isolen; - while (--fnlen >= 0) { - if (--isolen < 0) + for (; fn != fnend; fn++) { + if (isofn == isoend) 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') { + isofn += isochar(isofn, isoend, joliet_level, &c); + if (c == ';') { + if (*fn++ != ';') + return fn[-1]; + for (i = 0; fn != fnend; i = i * 10 + *fn++ - '0') + if (*fn < '0' || *fn > '9') return -1; - } - } - for (j = 0; --isolen >= 0; j = j * 10 + *isofn++ - '0'); + for (j = 0; isofn != isoend; j = j * 10 + c - '0') + isofn += isochar(isofn, isoend, + joliet_level, &c); return i - j; } if (c != *fn) { @@ -90,15 +117,19 @@ } else return *fn - c; } - fn++; } - if (isolen > 0) { - switch (*isofn) { + if (isofn != isoend) { + isofn += isochar(isofn, isoend, joliet_level, &c); + switch (c) { default: - return -1; + return -c; case '.': - if (isofn[1] != ';') - return -1; + if (isofn != isoend) { + isochar(isofn, isoend, joliet_level, &c); + if (c == ';') + return 0; + } + return -1; case ';': return 0; } @@ -107,35 +138,36 @@ } /* - * translate a filename + * translate a filename of length > 0 */ void -isofntrans(infn, infnlen, outfn, outfnlen, original, assoc) +isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level) u_char *infn; int infnlen; u_char *outfn; u_short *outfnlen; int original; int assoc; + int joliet_level; { int fnidx = 0; + u_char c, d = '\0', *infnend = infn + infnlen; if (assoc) { *outfn++ = ASSOCCHAR; fnidx++; - infnlen++; } - for (; fnidx < infnlen; fnidx++) { - char c = *infn++; + for (; infn != infnend; fnidx++) { + infn += isochar(infn, infnend, joliet_level, &c); if (!original && c >= 'A' && c <= 'Z') *outfn++ = c + ('a' - 'A'); - else if (!original && c == '.' && *infn == ';') - break; - else if (!original && c == ';') + else if (!original && c == ';') { + fnidx -= (d == '.'); break; - else + } else *outfn++ = c; + d = c; } *outfnlen = fnidx; } Index: sys/isofs/cd9660/cd9660_vfsops.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_vfsops.c,v retrieving revision 1.35 diff -u -r1.35 cd9660_vfsops.c --- cd9660_vfsops.c 1998/03/08 09:56:41 1.35 +++ cd9660_vfsops.c 1998/03/16 19:07:13 @@ -271,9 +271,12 @@ int ronly = (mp->mnt_flag & MNT_RDONLY) != 0; int iso_bsize; int iso_blknum; + int pri_blknum; + int joliet_level; struct iso_volume_descriptor *vdp = 0; struct iso_primary_descriptor *pri; struct iso_sierra_primary_descriptor *pri_sierra; + struct iso_supplementary_descriptor *supp; struct iso_directory_record *rootp; int logical_block_size; @@ -303,6 +306,8 @@ */ iso_bsize = ISO_DEFAULT_BLOCK_SIZE; + joliet_level = 0; + pri_blknum = -1; for (iso_blknum = 16 + argp->ssector; iso_blknum < 100 + argp->ssector; iso_blknum++) { @@ -320,19 +325,42 @@ high_sierra = 1; } - if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) == ISO_VD_END) { - error = EINVAL; - goto out; - } + if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) == ISO_VD_END) + break; if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) == ISO_VD_PRIMARY) - break; + pri_blknum = iso_blknum; + + if (!(argp->flags & ISOFSMNT_NOJOLIET) && + isonum_711 (high_sierra? vdp->type_sierra: vdp->type) == ISO_VD_SUPPLEMENTARY) { + supp = (struct iso_supplementary_descriptor *)vdp; + if (bcmp(supp->escape, "%/@", 3) == 0) + joliet_level = 1; + if (bcmp(supp->escape, "%/C", 3) == 0) + joliet_level = 2; + if (bcmp(supp->escape, "%/E", 3) == 0) + joliet_level = 3; + if (isonum_711 (supp->flags) & 1) + joliet_level = 0; + if (joliet_level) + break; + } + brelse(bp); } - if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) != ISO_VD_PRIMARY) { - error = EINVAL; - goto out; + if (isonum_711 (high_sierra? vdp->type_sierra: vdp->type) != ISO_VD_SUPPLEMENTARY) { + if (pri_blknum == -1) { + error = EINVAL; + goto out; + } + + brelse(bp); + if (error = bread(devvp, pri_blknum * btodb(iso_bsize), + iso_bsize, NOCRED, &bp)) + goto out; + vdp = (struct iso_volume_descriptor *)bp->b_data; + argp->flags |= ISOFSMNT_NOJOLIET; } pri = (struct iso_primary_descriptor *)vdp; @@ -361,6 +389,7 @@ isonum_733 (high_sierra? pri_sierra->volume_space_size: pri->volume_space_size); + isomp->joliet_level = joliet_level; /* * Since an ISO9660 multi-session CD can also access previous * sessions, we have to include them into the space consider- @@ -375,9 +404,7 @@ 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++; + isomp->im_bshift = ffs(logical_block_size) - 1; bp->b_flags |= B_AGE; brelse(bp); @@ -418,7 +445,8 @@ brelse(bp); bp = NULL; } - isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT); + isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS | + ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET); if(high_sierra) /* this effectively ignores all the mount flags */ Index: sys/isofs/cd9660/cd9660_vnops.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/cd9660_vnops.c,v retrieving revision 1.52 diff -u -r1.52 cd9660_vnops.c --- cd9660_vnops.c 1998/03/06 09:46:14 1.52 +++ cd9660_vnops.c 1998/03/16 18:16:01 @@ -549,26 +549,23 @@ break; default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA*/ strcpy(idp->current.d_name,".."); - switch (ep->name[0]) { - case 0: + if (idp->current.d_namlen == 1 && ep->name[0] == 0) { idp->current.d_namlen = 1; error = iso_uiodir(idp,&idp->current,idp->curroff); - break; - case 1: + } else if (idp->current.d_namlen == 1 && ep->name[0] == 1) { idp->current.d_namlen = 2; error = iso_uiodir(idp,&idp->current,idp->curroff); - break; - default: + } else { isofntrans(ep->name,idp->current.d_namlen, idp->current.d_name, &namelen, imp->iso_ftype == ISO_FTYPE_9660, - isonum_711(ep->flags)&4); + isonum_711(ep->flags)&4, + imp->joliet_level); idp->current.d_namlen = (u_char)namelen; if (imp->iso_ftype == ISO_FTYPE_DEFAULT) error = iso_shipdir(idp); else error = iso_uiodir(idp,&idp->current,idp->curroff); - break; } } if (error) Index: sys/isofs/cd9660/iso.h =================================================================== RCS file: /usr/CVS-Repository/src/sys/isofs/cd9660/iso.h,v retrieving revision 1.16 diff -u -r1.16 iso.h --- iso.h 1997/05/07 13:23:04 1.16 +++ iso.h 1998/03/16 19:10:03 @@ -54,6 +54,7 @@ /* volume descriptor types */ #define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 #define ISO_VD_END 255 #define ISO_STANDARD_ID "CD001" @@ -135,6 +136,42 @@ char unused4 [ISODCL (856, 2048)]; }; +struct iso_supplementary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char flags [ISODCL ( 8, 8)]; /* 711? */ + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char escape [ISODCL ( 89, 120)]; + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + struct iso_directory_record { char length [ISODCL (1, 1)]; /* 711 */ char ext_attr_length [ISODCL (2, 2)]; /* 711 */ @@ -202,6 +239,8 @@ int rr_skip; int rr_skip0; + + int joliet_level; }; #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data)) @@ -221,8 +260,9 @@ extern vop_t **cd9660_specop_p; extern vop_t **cd9660_fifoop_p; -int isofncmp __P((u_char *, int, u_char *, int)); -void isofntrans __P((u_char *, int, u_char *, u_short *, int, int)); +int isochar __P((u_char *, u_char *, int, u_char *)); +int isofncmp __P((u_char *, int, u_char *, int, int)); +void isofntrans __P((u_char *, int, u_char *, u_short *, int, int, int)); ino_t isodirino __P((struct iso_directory_record *, struct iso_mnt *)); #endif /* KERNEL */ Submit Followup ------------------------------------------------------------------------ www@freebsd.org To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-multimedia" in the body of the message