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: releng/10.2/sys/fs/cd9660/cd9660_util.c 278060 2015-02-02 07:42:03Z dim $"); 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; 83278060Sdim cd9660_iconv->convchr(handle, __DECONST(const char **, &inp), &i, 84278060Sdim &outp, &j); 85120492Sfjoe len -= j; 86120492Sfjoe if (clen) *clen = len; 87120492Sfjoe *c = '\0'; 88120492Sfjoe while(len--) 89120492Sfjoe *c |= (*(outp - len - 1) & 0xff) << (len << 3); 90120492Sfjoe } else { 91120492Sfjoe switch (*c) { 92120492Sfjoe default: 93120492Sfjoe *c = '?'; 94120492Sfjoe break; 95120492Sfjoe case '\0': 96120492Sfjoe *c = *isofn; 97120492Sfjoe break; 98120492Sfjoe } 9945773Sdcs } 10072435Ssobomax 10145773Sdcs return 2; 10245773Sdcs} 10345773Sdcs 10445773Sdcs/* 1051541Srgrimes * translate and compare a filename 10645773Sdcs * returns (fn - isofn) 1071541Srgrimes * Note: Version number plus ';' may be omitted. 1081541Srgrimes */ 1091541Srgrimesint 110120492Sfjoeisofncmp(fn, fnlen, isofn, isolen, joliet_level, flags, handle, lhandle) 11122593Sbde u_char *fn; 11222593Sbde int fnlen; 11322593Sbde u_char *isofn; 11422593Sbde int isolen; 11545773Sdcs int joliet_level; 116120492Sfjoe int flags; 117120492Sfjoe void *handle; 118120492Sfjoe void *lhandle; 1191541Srgrimes{ 1201541Srgrimes int i, j; 121120492Sfjoe u_short c, d; 122120492Sfjoe u_char *fnend = fn + fnlen, *isoend = isofn + isolen; 1238876Srgrimes 124120492Sfjoe for (; fn < fnend; ) { 125278060Sdim d = sgetrune(fn, fnend - fn, __DECONST(const char **, &fn), 126278060Sdim flags, lhandle); 12745773Sdcs if (isofn == isoend) 128120492Sfjoe return d; 129120492Sfjoe isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); 13045773Sdcs if (c == ';') { 131120492Sfjoe if (d != ';') 132120492Sfjoe return d; 133120492Sfjoe for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') { 1341541Srgrimes if (*fn < '0' || *fn > '9') { 1351541Srgrimes return -1; 1361541Srgrimes } 1371541Srgrimes } 13845773Sdcs for (j = 0; isofn != isoend; j = j * 10 + c - '0') 13945773Sdcs isofn += isochar(isofn, isoend, 140120492Sfjoe joliet_level, &c, 141120492Sfjoe NULL, flags, handle); 1421541Srgrimes return i - j; 1431541Srgrimes } 144120492Sfjoe if (c != d) { 1451541Srgrimes if (c >= 'A' && c <= 'Z') { 146120492Sfjoe if (c + ('a' - 'A') != d) { 147120492Sfjoe if (d >= 'a' && d <= 'z') 148120492Sfjoe return d - ('a' - 'A') - c; 1491541Srgrimes else 150120492Sfjoe return d - c; 1511541Srgrimes } 1521541Srgrimes } else 153120492Sfjoe return d - c; 1541541Srgrimes } 1551541Srgrimes } 15645773Sdcs if (isofn != isoend) { 157120492Sfjoe isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); 15845773Sdcs switch (c) { 1591541Srgrimes default: 16045773Sdcs return -c; 16145773Sdcs case '.': 16245773Sdcs if (isofn != isoend) { 163120492Sfjoe isochar(isofn, isoend, joliet_level, &c, 164120492Sfjoe NULL, flags, handle); 16545773Sdcs if (c == ';') 16645773Sdcs return 0; 16745773Sdcs } 1681541Srgrimes return -1; 1691541Srgrimes case ';': 1701541Srgrimes return 0; 1711541Srgrimes } 1721541Srgrimes } 1731541Srgrimes return 0; 1741541Srgrimes} 1751541Srgrimes 1761541Srgrimes/* 17745773Sdcs * translate a filename of length > 0 1781541Srgrimes */ 1791541Srgrimesvoid 180120492Sfjoeisofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level, flags, handle) 18122593Sbde u_char *infn; 18222521Sdyson int infnlen; 18322593Sbde u_char *outfn; 18422521Sdyson u_short *outfnlen; 18522521Sdyson int original; 18622521Sdyson int assoc; 18745773Sdcs int joliet_level; 188120492Sfjoe int flags; 189120492Sfjoe void *handle; 1901541Srgrimes{ 191120492Sfjoe u_short c, d = '\0'; 192120492Sfjoe u_char *outp = outfn, *infnend = infn + infnlen; 193120492Sfjoe int clen; 1948876Srgrimes 1951541Srgrimes if (assoc) { 196120492Sfjoe *outp++ = ASSOCCHAR; 1971541Srgrimes } 198120492Sfjoe for (; infn != infnend; ) { 199120492Sfjoe infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle); 2008876Srgrimes 20146669Sdcs if (!original && !joliet_level && c >= 'A' && c <= 'Z') 202120492Sfjoe c += ('a' - 'A'); 20345773Sdcs else if (!original && c == ';') { 204120492Sfjoe outp -= (d == '.'); 2051541Srgrimes break; 206120492Sfjoe } 20745773Sdcs d = c; 208120492Sfjoe while(clen--) 209120492Sfjoe *outp++ = c >> (clen << 3); 2101541Srgrimes } 211120492Sfjoe *outfnlen = outp - outfn; 2121541Srgrimes} 213120492Sfjoe 214120492Sfjoe/* 215120492Sfjoe * same as sgetrune(3) 216120492Sfjoe */ 217120492Sfjoeu_short 218120492Sfjoesgetrune(string, n, result, flags, handle) 219120492Sfjoe const char *string; 220120492Sfjoe size_t n; 221120492Sfjoe char const **result; 222120492Sfjoe int flags; 223120492Sfjoe void *handle; 224120492Sfjoe{ 225120492Sfjoe size_t i, j, len; 226120492Sfjoe char outbuf[3], *outp; 227120492Sfjoe u_short c = '\0'; 228120492Sfjoe 229120492Sfjoe len = i = (n < 2) ? n : 2; 230120492Sfjoe j = 2; 231120492Sfjoe outp = outbuf; 232120492Sfjoe 233120492Sfjoe if (flags & ISOFSMNT_KICONV && cd9660_iconv) { 234120492Sfjoe cd9660_iconv->convchr(handle, (const char **)&string, 235120492Sfjoe &i, &outp, &j); 236120492Sfjoe len -= i; 237120492Sfjoe } else { 238120492Sfjoe len = 1; 239120492Sfjoe string++; 240120492Sfjoe } 241120492Sfjoe 242120492Sfjoe if (result) *result = string; 243120492Sfjoe while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3); 244120492Sfjoe return (c); 245120492Sfjoe} 246