diff options
| author | scw <scw@NetBSD.org> | 1999-07-13 11:12:05 +0000 |
|---|---|---|
| committer | scw <scw@NetBSD.org> | 1999-07-13 11:12:05 +0000 |
| commit | 801242dfdcd5bdbe169ce5b7138f4e079753cc8e (patch) | |
| tree | 099b35a6a83cdc43ba5e5a3b6e8cd0ca3613ed38 /sys | |
| parent | 109518b89d9d0f3a4a577bcb554a74b1cfd2c286 (diff) | |
From patch supplied in PR-7951 by Joachim Kuebart:
Add support for Microsoft Joliet long filename extensions to the
cd9660 filesystem.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/isofs/cd9660/cd9660_extern.h | 8 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_lookup.c | 5 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_mount.h | 3 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_rrip.c | 25 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_util.c | 82 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_vfsops.c | 89 | ||||
| -rw-r--r-- | sys/isofs/cd9660/cd9660_vnops.c | 16 | ||||
| -rw-r--r-- | sys/isofs/cd9660/iso.h | 39 |
8 files changed, 205 insertions, 62 deletions
diff --git a/sys/isofs/cd9660/cd9660_extern.h b/sys/isofs/cd9660/cd9660_extern.h index bff9b621259..3167676d3c6 100644 --- a/sys/isofs/cd9660/cd9660_extern.h +++ b/sys/isofs/cd9660/cd9660_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_extern.h,v 1.6 1999/02/26 23:44:44 wrstuden Exp $ */ +/* $NetBSD: cd9660_extern.h,v 1.7 1999/07/13 11:12:05 scw Exp $ */ /*- * Copyright (c) 1994 @@ -53,6 +53,7 @@ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_E struct iso_mnt { int im_flags; + int im_joliet_level; struct mount *im_mountp; dev_t im_dev; @@ -106,6 +107,7 @@ extern int (**cd9660_vnodeop_p) __P((void *)); extern int (**cd9660_specop_p) __P((void *)); extern int (**cd9660_fifoop_p) __P((void *)); -int isofncmp __P((const u_char *, int, const u_char *, int)); -void isofntrans __P((u_char *, int, u_char *, u_short *, int, int)); +int isochar __P((const u_char *, const u_char *, int, u_char *)); +int isofncmp __P((const u_char *, int, const 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 *)); diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c index e887213b4f8..0fa403e3d18 100644 --- a/sys/isofs/cd9660/cd9660_lookup.c +++ b/sys/isofs/cd9660/cd9660_lookup.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_lookup.c,v 1.22 1999/07/08 01:06:00 wrstuden Exp $ */ +/* $NetBSD: cd9660_lookup.c,v 1.23 1999/07/13 11:12:05 scw Exp $ */ /*- * Copyright (c) 1989, 1993, 1994 @@ -321,7 +321,8 @@ searchloop: || ep->name[0] != 0) goto notfound; } else if (!(res = isofncmp(name,len, - ep->name,namelen))) { + ep->name,namelen, + imp->im_joliet_level))) { if (isonum_711(ep->flags)&2) ino = isodirino(ep, imp); else diff --git a/sys/isofs/cd9660/cd9660_mount.h b/sys/isofs/cd9660/cd9660_mount.h index 0970020edd5..9511cafb627 100644 --- a/sys/isofs/cd9660/cd9660_mount.h +++ b/sys/isofs/cd9660/cd9660_mount.h @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_mount.h,v 1.2 1998/03/01 02:27:49 fvdl Exp $ */ +/* $NetBSD: cd9660_mount.h,v 1.3 1999/07/13 11:12:05 scw Exp $ */ /* * Copyright (c) 1995 * The Regents of the University of California. All rights reserved. @@ -50,3 +50,4 @@ struct iso_args { #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 extensions */ diff --git a/sys/isofs/cd9660/cd9660_rrip.c b/sys/isofs/cd9660/cd9660_rrip.c index 287cb0a0bb2..b6025bf217f 100644 --- a/sys/isofs/cd9660/cd9660_rrip.c +++ b/sys/isofs/cd9660/cd9660_rrip.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_rrip.c,v 1.18 1998/08/09 20:42:54 perry Exp $ */ +/* $NetBSD: cd9660_rrip.c,v 1.19 1999/07/13 11:12:06 scw Exp $ */ /*- * Copyright (c) 1993, 1994 @@ -298,17 +298,19 @@ cd9660_rrip_defname(v, ana) { struct iso_directory_record *isodir = v; - 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->im_joliet_level); + switch (ana->outbuf[0]) { default: - isofntrans(isodir->name, isonum_711(isodir->name_len), - ana->outbuf, ana->outlen, - 1, isonum_711(isodir->flags) & 4); break; case 0: + ana->outbuf[0] = '.'; *ana->outlen = 1; break; case 1: + strcpy(ana->outbuf, ".."); *ana->outlen = 2; break; } @@ -518,6 +520,7 @@ cd9660_rrip_loop(isodir, ana, table) register ISO_SUSP_HEADER *pend; struct buf *bp = NULL; char *pwhead; + u_char c; int result; /* @@ -527,10 +530,10 @@ cd9660_rrip_loop(isodir, ana, table) pwhead = isodir->name + isonum_711(isodir->name_len); if (!(isonum_711(isodir->name_len) & 1)) pwhead++; + isochar(isodir->name, pwhead, ana->imp->im_joliet_level, &c); /* 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; @@ -648,6 +651,7 @@ cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp) { ISO_RRIP_ANALYZE analyze; RRIP_TABLE *tab; + u_char c; analyze.outbuf = outbuf; analyze.outlen = outlen; @@ -657,9 +661,10 @@ cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp) analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK | ISO_SUSP_PLINK; *outlen = 0; + isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), + imp->im_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 --git a/sys/isofs/cd9660/cd9660_util.c b/sys/isofs/cd9660/cd9660_util.c index e61ce890f05..6dcbb8b5f54 100644 --- a/sys/isofs/cd9660/cd9660_util.c +++ b/sys/isofs/cd9660/cd9660_util.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_util.c,v 1.12 1997/01/24 00:27:33 cgd Exp $ */ +/* $NetBSD: cd9660_util.c,v 1.13 1999/07/13 11:12:06 scw Exp $ */ /*- * Copyright (c) 1994 @@ -59,21 +59,51 @@ #include <isofs/cd9660/cd9660_extern.h> /* + * Get one character out of an iso filename + * Return number of bytes consumed + */ +int +isochar(isofn, isoend, joliet_level, c) + const u_char *isofn; + const 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 * Note: Version number plus ';' may be omitted. */ int -isofncmp(fn, fnlen, isofn, isolen) +isofncmp(fn, fnlen, isofn, isolen, joliet_level) const u_char *fn, *isofn; - int fnlen, isolen; + int fnlen, isolen, joliet_level; { int i, j; char c; - + const u_char *isoend = isofn + isolen; + while (--fnlen >= 0) { - if (--isolen < 0) + if (isofn == isoend) return *fn; - if ((c = *isofn++) == ';') { + isofn += isochar(isofn, isoend, joliet_level, &c); + if (c == ';') { switch (*fn++) { default: return *--fn; @@ -87,7 +117,9 @@ isofncmp(fn, fnlen, isofn, isolen) 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 (((u_char) c) != *fn) { @@ -103,13 +135,18 @@ isofncmp(fn, fnlen, isofn, isolen) } fn++; } - if (isolen > 0) { - switch (*isofn) { + if (isofn != isoend) { + isofn += isochar(isofn, isoend, joliet_level, &c); + switch (c) { default: return -1; case '.': - if (isofn[1] != ';') - return -1; + if (isofn != isoend) { + isochar(isofn, isoend, joliet_level, &c); + if (c == ';') + return 0; + } + return -1; case ';': return 0; } @@ -121,30 +158,33 @@ isofncmp(fn, fnlen, isofn, isolen) * translate a filename */ void -isofntrans(infn, infnlen, outfn, outfnlen, original, assoc) +isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level) u_char *infn, *outfn; int infnlen; u_short *outfnlen; int original; int assoc; + int joliet_level; { int fnidx = 0; + u_char *infnend = infn + infnlen; if (assoc) { *outfn++ = ASSOCCHAR; fnidx++; - infnlen++; } - for (; fnidx < infnlen; fnidx++) { - char c = *infn++; - - if (!original && c >= 'A' && c <= 'Z') + for (; infn != infnend; fnidx++) { + char c; + + infn += isochar(infn, infnend, joliet_level, &c); + + if (!original && joliet_level == 0 && c >= 'A' && c <= 'Z') *outfn++ = c + ('a' - 'A'); - else if (!original && c == '.' && *infn == ';') - break; - else if (!original && c == ';') + else if (!original && c == ';') { + if (fnidx > 0 && outfn[-1] == '.') + fnidx--; break; - else + } else *outfn++ = c; } *outfnlen = fnidx; diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 2a73757dd87..9e101c1cd19 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_vfsops.c,v 1.37 1999/07/08 01:06:01 wrstuden Exp $ */ +/* $NetBSD: cd9660_vfsops.c,v 1.38 1999/07/13 11:12:06 scw Exp $ */ /*- * Copyright (c) 1994 @@ -242,7 +242,7 @@ iso_mountfs(devvp, mp, p, argp) struct iso_args *argp; { register struct iso_mnt *isomp = (struct iso_mnt *)0; - struct buf *bp = NULL; + struct buf *bp = NULL, *pribp = NULL, *supbp = NULL; dev_t dev = devvp->v_rdev; int error = EINVAL; int needclose = 0; @@ -250,8 +250,10 @@ iso_mountfs(devvp, mp, p, argp) extern struct vnode *rootvp; int iso_bsize; int iso_blknum; + int joliet_level; struct iso_volume_descriptor *vdp; struct iso_primary_descriptor *pri; + struct iso_supplementary_descriptor *sup; struct iso_directory_record *rootp; int logical_block_size; int sess = 0; @@ -301,23 +303,70 @@ iso_mountfs(devvp, mp, p, argp) error = EINVAL; goto out; } - - if (isonum_711 (vdp->type) == ISO_VD_END) { - error = EINVAL; - goto out; + + switch (isonum_711(vdp->type)) { + case ISO_VD_PRIMARY: + if (pribp == NULL) { + pribp = bp; + bp = NULL; + } + break; + + case ISO_VD_SUPPLEMENTARY: + if (supbp == NULL) { + supbp = bp; + bp = NULL; + } + break; + + default: + break; } - - if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) + + if (isonum_711 (vdp->type) == ISO_VD_END) { + brelse(bp); + bp = NULL; break; - brelse(bp); + } + + if (bp != NULL) { + brelse(bp); + bp = NULL; + } } - - if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) { + + /* Check the Joliet Extension support */ + joliet_level = 0; + if ((argp->flags & ISOFSMNT_NOJOLIET) == 0 && supbp != NULL) { + sup = (struct iso_supplementary_descriptor *)supbp->b_data; + + if ((isonum_711(sup->flags) & 1) == 0) { + if (memcmp(sup->escape, "%/@", 3) == 0) + joliet_level = 1; + if (memcmp(sup->escape, "%/C", 3) == 0) + joliet_level = 2; + if (memcmp(sup->escape, "%/E", 3) == 0) + joliet_level = 3; + } + if (joliet_level != 0) { + if (pribp != NULL) + brelse(pribp); + pribp = supbp; + supbp = NULL; + } + } + + if (supbp != NULL) { + brelse(supbp); + supbp = NULL; + } + + if (pribp == NULL) { error = EINVAL; goto out; } - - pri = (struct iso_primary_descriptor *)vdp; + + pri = (struct iso_primary_descriptor *)pribp->b_data; logical_block_size = isonum_723 (pri->logical_block_size); @@ -336,15 +385,16 @@ iso_mountfs(devvp, mp, p, argp) memcpy(isomp->root, rootp, sizeof(isomp->root)); isomp->root_extent = isonum_733 (rootp->extent); isomp->root_size = isonum_733 (rootp->size); + isomp->im_joliet_level = joliet_level; 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; + pribp->b_flags |= B_AGE; + brelse(pribp); + pribp = NULL; mp->mnt_data = (qaddr_t)isomp; mp->mnt_stat.f_fsid.val[0] = (long)dev; @@ -382,7 +432,8 @@ iso_mountfs(devvp, mp, p, argp) 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); switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) { default: isomp->iso_ftype = ISO_FTYPE_DEFAULT; @@ -399,6 +450,10 @@ iso_mountfs(devvp, mp, p, argp) out: if (bp) brelse(bp); + if (pribp) + brelse(pribp); + if (supbp) + brelse(supbp); if (needclose) (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); if (isomp) { diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c index a92267d64d5..8273ec4c16f 100644 --- a/sys/isofs/cd9660/cd9660_vnops.c +++ b/sys/isofs/cd9660/cd9660_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_vnops.c,v 1.53 1999/07/08 01:06:01 wrstuden Exp $ */ +/* $NetBSD: cd9660_vnops.c,v 1.54 1999/07/13 11:12:06 scw Exp $ */ /*- * Copyright (c) 1994 @@ -550,21 +550,23 @@ cd9660_readdir(v) 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]) { + isofntrans(ep->name,idp->current.d_namlen, + idp->current.d_name, &namelen, + imp->iso_ftype == ISO_FTYPE_9660, + isonum_711(ep->flags)&4, + imp->im_joliet_level); + switch (idp->current.d_name[0]) { case 0: + idp->current.d_name[0] = '.'; idp->current.d_namlen = 1; error = iso_uiodir(idp,&idp->current,idp->curroff); break; case 1: + strcpy(idp->current.d_name,".."); 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, &namelen, - imp->iso_ftype == ISO_FTYPE_9660, - isonum_711(ep->flags)&4); idp->current.d_namlen = (u_char)namelen; if (imp->iso_ftype == ISO_FTYPE_DEFAULT) error = iso_shipdir(idp); diff --git a/sys/isofs/cd9660/iso.h b/sys/isofs/cd9660/iso.h index ca1bd8f2557..947d3c378e1 100644 --- a/sys/isofs/cd9660/iso.h +++ b/sys/isofs/cd9660/iso.h @@ -1,4 +1,4 @@ -/* $NetBSD: iso.h,v 1.21 1998/03/01 02:22:09 fvdl Exp $ */ +/* $NetBSD: iso.h,v 1.22 1999/07/13 11:12:06 scw Exp $ */ /*- * Copyright (c) 1994 @@ -57,6 +57,7 @@ struct iso_volume_descriptor { /* volume descriptor types */ #define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 #define ISO_VD_END 255 #define ISO_STANDARD_ID "CD001" @@ -99,6 +100,42 @@ struct iso_primary_descriptor { }; #define ISO_DEFAULT_BLOCK_SIZE 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 */ |
