cd9660_util.c revision 116181
11541Srgrimes/*- 21541Srgrimes * Copyright (c) 1994 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * This code is derived from software contributed to Berkeley 61541Srgrimes * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 71541Srgrimes * Support code is derived from software contributed to Berkeley 845773Sdcs * by Atsushi Murai (amurai@spec.co.jp). Joliet support was added by 945773Sdcs * Joachim Kuebart (joki@kuebart.stuttgart.netsurf.de). 101541Srgrimes * 111541Srgrimes * Redistribution and use in source and binary forms, with or without 121541Srgrimes * modification, are permitted provided that the following conditions 131541Srgrimes * are met: 141541Srgrimes * 1. Redistributions of source code must retain the above copyright 151541Srgrimes * notice, this list of conditions and the following disclaimer. 161541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171541Srgrimes * notice, this list of conditions and the following disclaimer in the 181541Srgrimes * documentation and/or other materials provided with the distribution. 191541Srgrimes * 3. All advertising materials mentioning features or use of this software 201541Srgrimes * must display the following acknowledgement: 211541Srgrimes * This product includes software developed by the University of 221541Srgrimes * California, Berkeley and its contributors. 231541Srgrimes * 4. Neither the name of the University nor the names of its contributors 241541Srgrimes * may be used to endorse or promote products derived from this software 251541Srgrimes * without specific prior written permission. 261541Srgrimes * 271541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 281541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 291541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 301541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 311541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 321541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 331541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 341541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 351541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 361541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 371541Srgrimes * SUCH DAMAGE. 381541Srgrimes * 3922521Sdyson * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94 401541Srgrimes */ 411541Srgrimes 42116181Sobrien#include <sys/cdefs.h> 43116181Sobrien__FBSDID("$FreeBSD: head/sys/fs/cd9660/cd9660_util.c 116181 2003-06-11 00:34:37Z obrien $"); 44116181Sobrien 451541Srgrimes#include <sys/param.h> 4696009Sjeff#include <sys/systm.h> 471541Srgrimes#include <sys/mount.h> 481541Srgrimes#include <sys/vnode.h> 491541Srgrimes 501541Srgrimes#include <isofs/cd9660/iso.h> 511541Srgrimes 521541Srgrimes/* 5372435Ssobomax * XXX: limited support for loading of Unicode 5472435Ssobomax * conversion routine as a kld at a run-time. 5572435Ssobomax * Should be removed when native Unicode kernel 5672435Ssobomax * interfaces have been introduced. 5772435Ssobomax */ 5872435Ssobomaxu_char (*cd9660_wchar2char)(u_int32_t wchar) = NULL; 5972435Ssobomax 6072435Ssobomax/* 6145773Sdcs * Get one character out of an iso filename 6245773Sdcs * Obey joliet_level 6345773Sdcs * Return number of bytes consumed 6445773Sdcs */ 6545773Sdcsint 6645773Sdcsisochar(isofn, isoend, joliet_level, c) 6745773Sdcs u_char *isofn; 6845773Sdcs u_char *isoend; 6945773Sdcs int joliet_level; 7045773Sdcs u_char *c; 7145773Sdcs{ 7245773Sdcs *c = *isofn++; 7345773Sdcs if (joliet_level == 0 || isofn == isoend) 7445773Sdcs /* (00) and (01) are one byte in Joliet, too */ 7545773Sdcs return 1; 7645773Sdcs 7745773Sdcs /* No Unicode support yet :-( */ 7845773Sdcs switch (*c) { 7945773Sdcs default: 8045773Sdcs *c = '?'; 8145773Sdcs break; 8245773Sdcs case '\0': 8345773Sdcs *c = *isofn; 8445773Sdcs break; 8545773Sdcs } 8672435Ssobomax /* XXX: if Unicode conversion routine is loaded then use it */ 8772435Ssobomax if (cd9660_wchar2char != NULL) 8872435Ssobomax *c = cd9660_wchar2char((*(isofn - 1) << 8) | *isofn); 8972435Ssobomax 9045773Sdcs return 2; 9145773Sdcs} 9245773Sdcs 9345773Sdcs/* 941541Srgrimes * translate and compare a filename 9545773Sdcs * returns (fn - isofn) 961541Srgrimes * Note: Version number plus ';' may be omitted. 971541Srgrimes */ 981541Srgrimesint 9945773Sdcsisofncmp(fn, fnlen, isofn, isolen, joliet_level) 10022593Sbde u_char *fn; 10122593Sbde int fnlen; 10222593Sbde u_char *isofn; 10322593Sbde int isolen; 10445773Sdcs int joliet_level; 1051541Srgrimes{ 1061541Srgrimes int i, j; 10745773Sdcs u_char c, *fnend = fn + fnlen, *isoend = isofn + isolen; 1088876Srgrimes 10945773Sdcs for (; fn != fnend; fn++) { 11045773Sdcs if (isofn == isoend) 1111541Srgrimes return *fn; 11245773Sdcs isofn += isochar(isofn, isoend, joliet_level, &c); 11345773Sdcs if (c == ';') { 11445773Sdcs if (*fn++ != ';') 11545773Sdcs return fn[-1]; 11645773Sdcs for (i = 0; fn != fnend; i = i * 10 + *fn++ - '0') { 1171541Srgrimes if (*fn < '0' || *fn > '9') { 1181541Srgrimes return -1; 1191541Srgrimes } 1201541Srgrimes } 12145773Sdcs for (j = 0; isofn != isoend; j = j * 10 + c - '0') 12245773Sdcs isofn += isochar(isofn, isoend, 12345773Sdcs joliet_level, &c); 1241541Srgrimes return i - j; 1251541Srgrimes } 1261541Srgrimes if (c != *fn) { 1271541Srgrimes if (c >= 'A' && c <= 'Z') { 1281541Srgrimes if (c + ('a' - 'A') != *fn) { 1291541Srgrimes if (*fn >= 'a' && *fn <= 'z') 1301541Srgrimes return *fn - ('a' - 'A') - c; 1311541Srgrimes else 1321541Srgrimes return *fn - c; 1331541Srgrimes } 1341541Srgrimes } else 1351541Srgrimes return *fn - c; 1361541Srgrimes } 1371541Srgrimes } 13845773Sdcs if (isofn != isoend) { 13945773Sdcs isofn += isochar(isofn, isoend, joliet_level, &c); 14045773Sdcs switch (c) { 1411541Srgrimes default: 14245773Sdcs return -c; 14345773Sdcs case '.': 14445773Sdcs if (isofn != isoend) { 14545773Sdcs isochar(isofn, isoend, joliet_level, &c); 14645773Sdcs if (c == ';') 14745773Sdcs return 0; 14845773Sdcs } 1491541Srgrimes return -1; 1501541Srgrimes case ';': 1511541Srgrimes return 0; 1521541Srgrimes } 1531541Srgrimes } 1541541Srgrimes return 0; 1551541Srgrimes} 1561541Srgrimes 1571541Srgrimes/* 15845773Sdcs * translate a filename of length > 0 1591541Srgrimes */ 1601541Srgrimesvoid 16145773Sdcsisofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level) 16222593Sbde u_char *infn; 16322521Sdyson int infnlen; 16422593Sbde u_char *outfn; 16522521Sdyson u_short *outfnlen; 16622521Sdyson int original; 16722521Sdyson int assoc; 16845773Sdcs int joliet_level; 1691541Srgrimes{ 1701541Srgrimes int fnidx = 0; 17145773Sdcs u_char c, d = '\0', *infnend = infn + infnlen; 1728876Srgrimes 1731541Srgrimes if (assoc) { 1741541Srgrimes *outfn++ = ASSOCCHAR; 1751541Srgrimes fnidx++; 1761541Srgrimes } 17745773Sdcs for (; infn != infnend; fnidx++) { 17845773Sdcs infn += isochar(infn, infnend, joliet_level, &c); 1798876Srgrimes 18046669Sdcs if (!original && !joliet_level && c >= 'A' && c <= 'Z') 1811541Srgrimes *outfn++ = c + ('a' - 'A'); 18245773Sdcs else if (!original && c == ';') { 18345773Sdcs fnidx -= (d == '.'); 1841541Srgrimes break; 18545773Sdcs } else 1861541Srgrimes *outfn++ = c; 18745773Sdcs d = c; 1881541Srgrimes } 1891541Srgrimes *outfnlen = fnidx; 1901541Srgrimes} 191