Annotation of src/sys/fs/cd9660/cd9660_util.c, Revision 1.13
1.13 ! christos 1: /* $NetBSD: cd9660_util.c,v 1.12 2014/11/10 18:46:33 maxv Exp $ */
1.1 jdolecek 2:
3: /*-
4: * Copyright (c) 1994
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley
8: * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
9: * Support code is derived from software contributed to Berkeley
10: * by Atsushi Murai (amurai@spec.co.jp).
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
1.2 agc 20: * 3. Neither the name of the University nor the names of its contributors
1.1 jdolecek 21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
37: */
38:
39: #include <sys/cdefs.h>
1.13 ! christos 40: #ifdef _KERNEL
! 41: __KERNEL_RCSID(0, "$NetBSD: cd9660_util.c,v 1.12 2014/11/10 18:46:33 maxv Exp $");
! 42: #else
! 43: /* used by macppc_installboot */
! 44: #if HAVE_NBTOOL_CONFIG_H
! 45: #include "nbtool_config.h"
! 46: #endif
! 47: #endif
1.1 jdolecek 48:
49: #include <sys/param.h>
1.13 ! christos 50: #ifdef _KERNEL
1.1 jdolecek 51: #include <sys/systm.h>
52: #include <sys/namei.h>
53: #include <sys/resourcevar.h>
54: #include <sys/kernel.h>
55: #include <sys/file.h>
56: #include <sys/stat.h>
57: #include <sys/buf.h>
58: #include <sys/proc.h>
59: #include <sys/mount.h>
60: #include <sys/vnode.h>
61: #include <sys/dirent.h>
1.13 ! christos 62: #else
! 63: #include <assert.h>
! 64: #include <dirent.h>
! 65: #define KASSERT(x) assert(x) /* XXX for <fs/unicode.h> */
! 66: #endif
1.1 jdolecek 67:
68: #include <fs/cd9660/iso.h>
1.13 ! christos 69: #ifdef _KERNEL
1.1 jdolecek 70: #include <fs/cd9660/cd9660_extern.h>
1.13 ! christos 71: #else
! 72: #include "installboot.h"
! 73: static int isochar(const u_char *, const u_char *, int, uint16_t *);
! 74: #endif
1.1 jdolecek 75:
1.3 jdolecek 76: #include <fs/unicode.h>
77:
1.13 ! christos 78: static uint16_t wget(const u_char **, size_t *, int);
! 79: static int wput(u_char *, size_t, uint16_t, int);
1.3 jdolecek 80:
81: int cd9660_utf8_joliet = 1;
82:
1.1 jdolecek 83: /*
84: * Get one character out of an iso filename
85: * Return number of bytes consumed
86: */
87: int
1.9 matt 88: isochar(const u_char *isofn, const u_char *isoend, int joliet_level,
1.13 ! christos 89: uint16_t *c)
1.1 jdolecek 90: {
1.13 ! christos 91:
1.3 jdolecek 92: *c = isofn[0];
93: if (joliet_level == 0 || isofn + 1 == isoend) {
1.1 jdolecek 94: /* (00) and (01) are one byte in Joliet, too */
95: return 1;
1.3 jdolecek 96: }
1.1 jdolecek 97:
1.3 jdolecek 98: if (cd9660_utf8_joliet) {
99: *c = (*c << 8) + isofn[1];
100: } else {
101: /* characters outside ISO-8859-1 subset replaced with '?' */
102: if (*c != 0)
103: *c = '?';
104: else
105: *c = isofn[1];
1.1 jdolecek 106: }
1.3 jdolecek 107:
1.1 jdolecek 108: return 2;
109: }
110:
111: /*
112: * translate and compare a filename
113: * Note: Version number plus ';' may be omitted.
114: */
115: int
1.9 matt 116: isofncmp(const u_char *fn, size_t fnlen, const u_char *isofn, size_t isolen,
1.13 ! christos 117: int joliet_level)
1.1 jdolecek 118: {
119: int i, j;
1.13 ! christos 120: uint16_t fc, ic;
1.1 jdolecek 121: const u_char *isoend = isofn + isolen;
122:
1.13 ! christos 123: #ifdef ISOFNCMPDEBUG
! 124: printf("fn = %s, fnlen = %zu, isofn = %s, isolen = %zu\n",
! 125: fn, fnlen, isofn, isolen);
! 126: #endif
! 127:
1.4 jdolecek 128: while (fnlen > 0) {
129: fc = wget(&fn, &fnlen, joliet_level);
1.3 jdolecek 130:
1.1 jdolecek 131: if (isofn == isoend)
1.3 jdolecek 132: return fc;
133: isofn += isochar(isofn, isoend, joliet_level, &ic);
134: if (ic == ';') {
135: switch (fc) {
1.1 jdolecek 136: default:
1.3 jdolecek 137: return fc;
1.1 jdolecek 138: case 0:
139: return 0;
140: case ';':
141: break;
142: }
1.7 christos 143: for (i = 0; fnlen-- != 0; i = i * 10 + *fn++ - '0') {
1.1 jdolecek 144: if (*fn < '0' || *fn > '9') {
145: return -1;
146: }
147: }
1.3 jdolecek 148: for (j = 0; isofn != isoend; j = j * 10 + ic - '0')
1.1 jdolecek 149: isofn += isochar(isofn, isoend,
1.3 jdolecek 150: joliet_level, &ic);
1.1 jdolecek 151: return i - j;
152: }
1.3 jdolecek 153: if (ic != fc) {
154: if (ic >= 'A' && ic <= 'Z') {
155: if (ic + ('a' - 'A') != fc) {
156: if (fc >= 'a' && fc <= 'z')
157: fc -= 'a' - 'A';
158:
1.13 ! christos 159: return (int)fc - (int)ic;
1.1 jdolecek 160: }
161: } else
1.13 ! christos 162: return (int)fc - (int)ic;
1.1 jdolecek 163: }
164: }
165: if (isofn != isoend) {
1.3 jdolecek 166: isofn += isochar(isofn, isoend, joliet_level, &ic);
167: switch (ic) {
1.1 jdolecek 168: default:
169: return -1;
170: case '.':
171: if (isofn != isoend) {
1.3 jdolecek 172: isochar(isofn, isoend, joliet_level, &ic);
173: if (ic == ';')
1.1 jdolecek 174: return 0;
175: }
176: return -1;
177: case ';':
178: return 0;
179: }
180: }
181: return 0;
182: }
183:
184: /*
185: * translate a filename
186: */
187: void
1.9 matt 188: isofntrans(const u_char *infn, int infnlen, u_char *outfn, u_short *outfnlen,
1.13 ! christos 189: int original, int casetrans, int assoc, int joliet_level)
1.1 jdolecek 190: {
191: int fnidx = 0;
1.9 matt 192: const u_char *infnend = infn + infnlen;
1.13 ! christos 193: uint16_t c;
1.3 jdolecek 194: int sz;
195:
1.1 jdolecek 196: if (assoc) {
197: *outfn++ = ASSOCCHAR;
198: fnidx++;
199: }
200:
1.3 jdolecek 201: for(; infn != infnend; fnidx += sz) {
1.1 jdolecek 202: infn += isochar(infn, infnend, joliet_level, &c);
203:
204: if (casetrans && joliet_level == 0 && c >= 'A' && c <= 'Z')
1.3 jdolecek 205: c = c + ('a' - 'A');
1.1 jdolecek 206: else if (!original && c == ';') {
207: if (fnidx > 0 && outfn[-1] == '.')
208: fnidx--;
209: break;
1.3 jdolecek 210: }
211:
1.10 christos 212: sz = wput(outfn, ISO_MAXNAMLEN - fnidx, c, joliet_level);
1.3 jdolecek 213: if (sz == 0) {
214: /* not enough space to write the character */
1.10 christos 215: if (fnidx < ISO_MAXNAMLEN) {
1.3 jdolecek 216: *outfn = '?';
217: fnidx++;
218: }
219: break;
220: }
221: outfn += sz;
1.1 jdolecek 222: }
223: *outfnlen = fnidx;
224: }
1.3 jdolecek 225:
1.13 ! christos 226: static uint16_t
1.4 jdolecek 227: wget(const u_char **str, size_t *sz, int joliet_level)
1.3 jdolecek 228: {
229: if (joliet_level > 0 && cd9660_utf8_joliet) {
230: /* decode UTF-8 sequence */
1.4 jdolecek 231: return wget_utf8((const char **) str, sz);
1.3 jdolecek 232: } else {
233: /*
234: * Raw 8-bit characters without any conversion. For Joliet,
235: * this effectively assumes provided file name is using
236: * ISO-8859-1 subset.
237: */
1.13 ! christos 238: uint16_t c = *str[0];
1.3 jdolecek 239: (*str)++;
1.8 enami 240: (*sz)--;
1.3 jdolecek 241:
242: return c;
243: }
244: }
245:
246: static int
1.13 ! christos 247: wput(u_char *s, size_t n, uint16_t c, int joliet_level)
1.3 jdolecek 248: {
249: if (joliet_level > 0 && cd9660_utf8_joliet) {
250: /* Store Joliet file name encoded into UTF-8 */
251: return wput_utf8((char *)s, n, c);
252: } else {
253: /*
254: * Store raw 8-bit characters without any conversion.
255: * For Joliet case, this filters the Unicode characters
256: * to ISO-8859-1 subset.
257: */
258: *s = (u_char)c;
259: return 1;
260: }
261: }
CVSweb <webmaster@jp.NetBSD.org>