Date: Sat, 31 Oct 1998 15:00:01 -0800 (PST) From: Alex Vasylenko <lxv@nest.org> To: freebsd-bugs@FreeBSD.ORG Subject: Re: kern/5038: FreeBSD can't read MS Joliet CDs. Message-ID: <199810312300.PAA06804@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/5038; it has been noted by GNATS.
From: Alex Vasylenko <lxv@nest.org>
To: freebsd-gnats-submit@freebsd.org,
Joachim Kuebart <joki@kuebart.stuttgart.netsurf.de>
Cc: Subject: Re: kern/5038: FreeBSD can't read MS Joliet CDs.
Date: Sat, 31 Oct 1998 14:53:34 -0800
hi,
below is a diff from -stable (as of 10/30) sources to support Joliet
extensions to cd9660 filesystem (author Joachim Kuebart
<joki@kuebart.stuttgart.netsurf.de>) ...
--Alex.
===== ~/s/src/sys/isofs/cd9660
diff -u orig/cd9660_lookup.c ./cd9660_lookup.c
--- orig/cd9660_lookup.c Sun Aug 17 06:28:32 1997
+++ ./cd9660_lookup.c Fri Oct 30 23:41:48 1998
@@ -308,8 +308,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)
isodirino(&ino,ep,imp);
else
diff -u orig/cd9660_mount.h ./cd9660_mount.h
--- orig/cd9660_mount.h Sun Aug 17 06:28:33 1997
+++ ./cd9660_mount.h Fri Oct 30 23:45:01 1998
@@ -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. */
diff -u orig/cd9660_rrip.c ./cd9660_rrip.c
--- orig/cd9660_rrip.c Sun Aug 17 06:28:37 1997
+++ ./cd9660_rrip.c Fri Oct 30 23:48:14 1998
@@ -306,18 +306,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;
}
}
@@ -509,6 +510,7 @@
register ISO_SUSP_HEADER *pend;
struct buf *bp = NULL;
char *pwhead;
+ u_char c;
int result;
/*
@@ -516,12 +518,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;
@@ -635,6 +636,7 @@
{
ISO_RRIP_ANALYZE analyze;
RRIP_TABLE *tab;
+ u_char c;
analyze.outbuf = outbuf;
analyze.outlen = outlen;
@@ -644,9 +646,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;
diff -u orig/cd9660_util.c ./cd9660_util.c
--- orig/cd9660_util.c Sun Aug 17 06:28:39 1997
+++ ./cd9660_util.c Sat Oct 31 01:26:58 1998
@@ -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
@@ -153,33 +154,63 @@
#endif /* __notanymore__ */
/*
+ * 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(unsigned char *fn,int fnlen,unsigned char *isofn,int 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) {
@@ -193,15 +224,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;
}
@@ -210,31 +245,36 @@
}
/*
- * translate a filename
+ * translate a filename of length > 0
*/
void
-isofntrans(unsigned char *infn,int infnlen,
- unsigned char *outfn,unsigned short *outfnlen,
- int original,int 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;
}
diff -u orig/cd9660_vfsops.c ./cd9660_vfsops.c
--- orig/cd9660_vfsops.c Sun Mar 29 03:10:36 1998
+++ ./cd9660_vfsops.c Sat Oct 31 00:31:56 1998
@@ -294,9 +294,12 @@
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
int iso_bsize;
int iso_blknum;
- struct iso_volume_descriptor *vdp;
+ 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;
@@ -326,6 +329,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++) {
@@ -343,19 +348,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;
@@ -384,6 +412,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-
@@ -398,9 +427,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);
@@ -441,7 +468,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 */
diff -u orig/cd9660_vnops.c ./cd9660_vnops.c
--- orig/cd9660_vnops.c Sun Aug 17 06:28:42 1997
+++ ./cd9660_vnops.c Sat Oct 31 01:23:04 1998
@@ -679,26 +679,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, &elen,
imp->iso_ftype == ISO_FTYPE_9660,
- isoflags & 4);
+ isoflags & 4,
+ imp->joliet_level);
idp->current.d_namlen = (u_char)elen;
if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
error = iso_shipdir(idp);
else
error = iso_uiodir(idp,&idp->current,idp->curroff);
- break;
}
}
if (error)
diff -u orig/iso.h ./iso.h
--- orig/iso.h Tue Jul 7 11:11:16 1998
+++ ./iso.h Sat Oct 31 01:39:39 1998
@@ -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 */
@@ -203,6 +240,8 @@
int rr_skip;
int rr_skip0;
+
+ int joliet_level;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
@@ -227,9 +266,9 @@
extern vop_t **cd9660_vnodeop_p;
-int isofncmp __P((unsigned char *, int, unsigned char *, int));
-void isofntrans __P((unsigned char *, int, unsigned char *, unsigned 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));
#endif /* KERNEL */
===== ~/s/src/sys/sys
diff -u orig/mount.h ./mount.h
--- orig/mount.h Tue Jul 21 10:50:37 1998
+++ ./mount.h Sat Oct 31 10:36:45 1998
@@ -420,6 +420,7 @@
#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. */
#endif /* CD9660 */
#ifdef NFS
===== ~/s/src/sbin/mount_cd9660
diff -u orig/mount_cd9660.8 ./mount_cd9660.8
--- orig/mount_cd9660.8 Tue Jul 21 10:48:07 1998
+++ ./mount_cd9660.8 Sat Oct 31 01:48:25 1998
@@ -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
diff -u orig/mount_cd9660.c ./mount_cd9660.c
--- orig/mount_cd9660.c Sun Aug 17 06:30:23 1997
+++ ./mount_cd9660.c Sat Oct 31 01:49:31 1998
@@ -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);
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810312300.PAA06804>
