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 * 4. Neither the name of the University nor the names of its contributors 201541Srgrimes * may be used to endorse or promote products derived from this software 211541Srgrimes * without specific prior written permission. 221541Srgrimes * 231541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 241541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 271541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331541Srgrimes * SUCH DAMAGE. 341541Srgrimes * 3522521Sdyson * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94 361541Srgrimes */ 371541Srgrimes 38116181Sobrien#include <sys/cdefs.h> 39116181Sobrien__FBSDID("$FreeBSD$"); 40116181Sobrien 411541Srgrimes#include <sys/param.h> 4296009Sjeff#include <sys/systm.h> 431541Srgrimes#include <sys/mount.h> 441541Srgrimes#include <sys/vnode.h> 45120492Sfjoe#include <sys/iconv.h> 461541Srgrimes 47166639Srodrigc#include <fs/cd9660/iso.h> 48166639Srodrigc#include <fs/cd9660/cd9660_mount.h> 491541Srgrimes 50120492Sfjoeextern struct iconv_functions *cd9660_iconv; 5172435Ssobomax 5272435Ssobomax/* 5345773Sdcs * Get one character out of an iso filename 5445773Sdcs * Obey joliet_level 5545773Sdcs * Return number of bytes consumed 5645773Sdcs */ 5745773Sdcsint 58120492Sfjoeisochar(isofn, isoend, joliet_level, c, clen, flags, handle) 5945773Sdcs u_char *isofn; 6045773Sdcs u_char *isoend; 6145773Sdcs int joliet_level; 62120492Sfjoe u_short *c; 63120492Sfjoe int *clen; 64120492Sfjoe int flags; 65120492Sfjoe void *handle; 6645773Sdcs{ 67120492Sfjoe size_t i, j, len; 68120492Sfjoe char inbuf[3], outbuf[3], *inp, *outp; 69120492Sfjoe 7045773Sdcs *c = *isofn++; 71120492Sfjoe if (clen) *clen = 1; 7245773Sdcs if (joliet_level == 0 || isofn == isoend) 7345773Sdcs /* (00) and (01) are one byte in Joliet, too */ 7445773Sdcs return 1; 7545773Sdcs 76120492Sfjoe if (flags & ISOFSMNT_KICONV && cd9660_iconv) { 77120492Sfjoe i = j = len = 2; 78120492Sfjoe inbuf[0]=(char)*(isofn - 1); 79120492Sfjoe inbuf[1]=(char)*isofn; 80120492Sfjoe inbuf[2]='\0'; 81120492Sfjoe inp = inbuf; 82120492Sfjoe outp = outbuf; 83120492Sfjoe cd9660_iconv->convchr(handle, (const char **)&inp, &i, &outp, &j); 84120492Sfjoe len -= j; 85120492Sfjoe if (clen) *clen = len; 86120492Sfjoe *c = '\0'; 87120492Sfjoe while(len--) 88120492Sfjoe *c |= (*(outp - len - 1) & 0xff) << (len << 3); 89120492Sfjoe } else { 90120492Sfjoe switch (*c) { 91120492Sfjoe default: 92120492Sfjoe *c = '?'; 93120492Sfjoe break; 94120492Sfjoe case '\0': 95120492Sfjoe *c = *isofn; 96120492Sfjoe break; 97120492Sfjoe } 9845773Sdcs } 9972435Ssobomax 10045773Sdcs return 2; 10145773Sdcs} 10245773Sdcs 10345773Sdcs/* 1041541Srgrimes * translate and compare a filename 10545773Sdcs * returns (fn - isofn) 1061541Srgrimes * Note: Version number plus ';' may be omitted. 1071541Srgrimes */ 1081541Srgrimesint 109120492Sfjoeisofncmp(fn, fnlen, isofn, isolen, joliet_level, flags, handle, lhandle) 11022593Sbde u_char *fn; 11122593Sbde int fnlen; 11222593Sbde u_char *isofn; 11322593Sbde int isolen; 11445773Sdcs int joliet_level; 115120492Sfjoe int flags; 116120492Sfjoe void *handle; 117120492Sfjoe void *lhandle; 1181541Srgrimes{ 1191541Srgrimes int i, j; 120120492Sfjoe u_short c, d; 121120492Sfjoe u_char *fnend = fn + fnlen, *isoend = isofn + isolen; 1228876Srgrimes 123120492Sfjoe for (; fn < fnend; ) { 124120492Sfjoe d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle); 12545773Sdcs if (isofn == isoend) 126120492Sfjoe return d; 127120492Sfjoe isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); 12845773Sdcs if (c == ';') { 129120492Sfjoe if (d != ';') 130120492Sfjoe return d; 131120492Sfjoe for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') { 1321541Srgrimes if (*fn < '0' || *fn > '9') { 1331541Srgrimes return -1; 1341541Srgrimes } 1351541Srgrimes } 13645773Sdcs for (j = 0; isofn != isoend; j = j * 10 + c - '0') 13745773Sdcs isofn += isochar(isofn, isoend, 138120492Sfjoe joliet_level, &c, 139120492Sfjoe NULL, flags, handle); 1401541Srgrimes return i - j; 1411541Srgrimes } 142120492Sfjoe if (c != d) { 1431541Srgrimes if (c >= 'A' && c <= 'Z') { 144120492Sfjoe if (c + ('a' - 'A') != d) { 145120492Sfjoe if (d >= 'a' && d <= 'z') 146120492Sfjoe return d - ('a' - 'A') - c; 1471541Srgrimes else 148120492Sfjoe return d - c; 1491541Srgrimes } 1501541Srgrimes } else 151120492Sfjoe return d - c; 1521541Srgrimes } 1531541Srgrimes } 15445773Sdcs if (isofn != isoend) { 155120492Sfjoe isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); 15645773Sdcs switch (c) { 1571541Srgrimes default: 15845773Sdcs return -c; 15945773Sdcs case '.': 16045773Sdcs if (isofn != isoend) { 161120492Sfjoe isochar(isofn, isoend, joliet_level, &c, 162120492Sfjoe NULL, flags, handle); 16345773Sdcs if (c == ';') 16445773Sdcs return 0; 16545773Sdcs } 1661541Srgrimes return -1; 1671541Srgrimes case ';': 1681541Srgrimes return 0; 1691541Srgrimes } 1701541Srgrimes } 1711541Srgrimes return 0; 1721541Srgrimes} 1731541Srgrimes 1741541Srgrimes/* 17545773Sdcs * translate a filename of length > 0 1761541Srgrimes */ 1771541Srgrimesvoid 178120492Sfjoeisofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level, flags, handle) 17922593Sbde u_char *infn; 18022521Sdyson int infnlen; 18122593Sbde u_char *outfn; 18222521Sdyson u_short *outfnlen; 18322521Sdyson int original; 18422521Sdyson int assoc; 18545773Sdcs int joliet_level; 186120492Sfjoe int flags; 187120492Sfjoe void *handle; 1881541Srgrimes{ 189120492Sfjoe u_short c, d = '\0'; 190120492Sfjoe u_char *outp = outfn, *infnend = infn + infnlen; 191120492Sfjoe int clen; 1928876Srgrimes 1931541Srgrimes if (assoc) { 194120492Sfjoe *outp++ = ASSOCCHAR; 1951541Srgrimes } 196120492Sfjoe for (; infn != infnend; ) { 197120492Sfjoe infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle); 1988876Srgrimes 19946669Sdcs if (!original && !joliet_level && c >= 'A' && c <= 'Z') 200120492Sfjoe c += ('a' - 'A'); 20145773Sdcs else if (!original && c == ';') { 202120492Sfjoe outp -= (d == '.'); 2031541Srgrimes break; 204120492Sfjoe } 20545773Sdcs d = c; 206120492Sfjoe while(clen--) 207120492Sfjoe *outp++ = c >> (clen << 3); 2081541Srgrimes } 209120492Sfjoe *outfnlen = outp - outfn; 2101541Srgrimes} 211120492Sfjoe 212120492Sfjoe/* 213120492Sfjoe * same as sgetrune(3) 214120492Sfjoe */ 215120492Sfjoeu_short 216120492Sfjoesgetrune(string, n, result, flags, handle) 217120492Sfjoe const char *string; 218120492Sfjoe size_t n; 219120492Sfjoe char const **result; 220120492Sfjoe int flags; 221120492Sfjoe void *handle; 222120492Sfjoe{ 223120492Sfjoe size_t i, j, len; 224120492Sfjoe char outbuf[3], *outp; 225120492Sfjoe u_short c = '\0'; 226120492Sfjoe 227120492Sfjoe len = i = (n < 2) ? n : 2; 228120492Sfjoe j = 2; 229120492Sfjoe outp = outbuf; 230120492Sfjoe 231120492Sfjoe if (flags & ISOFSMNT_KICONV && cd9660_iconv) { 232120492Sfjoe cd9660_iconv->convchr(handle, (const char **)&string, 233120492Sfjoe &i, &outp, &j); 234120492Sfjoe len -= i; 235120492Sfjoe } else { 236120492Sfjoe len = 1; 237120492Sfjoe string++; 238120492Sfjoe } 239120492Sfjoe 240120492Sfjoe if (result) *result = string; 241120492Sfjoe while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3); 242120492Sfjoe return (c); 243120492Sfjoe} 244