xref: /netbsd-src/sys/fs/cd9660/cd9660_util.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: cd9660_util.c,v 1.2 2003/08/07 16:31:35 agc Exp $	*/
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.
20  * 3. Neither the name of the University nor the names of its contributors
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>
40 __KERNEL_RCSID(0, "$NetBSD: cd9660_util.c,v 1.2 2003/08/07 16:31:35 agc Exp $");
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/namei.h>
45 #include <sys/resourcevar.h>
46 #include <sys/kernel.h>
47 #include <sys/file.h>
48 #include <sys/stat.h>
49 #include <sys/buf.h>
50 #include <sys/proc.h>
51 #include <sys/mount.h>
52 #include <sys/vnode.h>
53 #include <sys/malloc.h>
54 #include <sys/dirent.h>
55 
56 #include <fs/cd9660/iso.h>
57 #include <fs/cd9660/cd9660_extern.h>
58 
59 /*
60  * Get one character out of an iso filename
61  * Return number of bytes consumed
62  */
63 int
64 isochar(isofn, isoend, joliet_level, c)
65 	const u_char *isofn;
66 	const u_char *isoend;
67 	int joliet_level;
68 	u_char *c;
69 {
70 	*c = *isofn++;
71 	if (joliet_level == 0 || isofn == isoend)
72 		/* (00) and (01) are one byte in Joliet, too */
73 		return 1;
74 
75 	/* No Unicode support yet :-( */
76 	switch (*c) {
77 	default:
78 		*c = '?';
79 		break;
80 	case '\0':
81 		*c = *isofn;
82 		break;
83 	}
84 	return 2;
85 }
86 
87 /*
88  * translate and compare a filename
89  * Note: Version number plus ';' may be omitted.
90  */
91 int
92 isofncmp(fn, fnlen, isofn, isolen, joliet_level)
93 	const u_char *fn, *isofn;
94 	int fnlen, isolen, joliet_level;
95 {
96 	int i, j;
97 	char c;
98 	const u_char *isoend = isofn + isolen;
99 
100 	while (--fnlen >= 0) {
101 		if (isofn == isoend)
102 			return *fn;
103 		isofn += isochar(isofn, isoend, joliet_level, &c);
104 		if (c == ';') {
105 			switch (*fn++) {
106 			default:
107 				return *--fn;
108 			case 0:
109 				return 0;
110 			case ';':
111 				break;
112 			}
113 			for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') {
114 				if (*fn < '0' || *fn > '9') {
115 					return -1;
116 				}
117 			}
118 			for (j = 0; isofn != isoend; j = j * 10 + c - '0')
119 				isofn += isochar(isofn, isoend,
120 						 joliet_level, &c);
121 			return i - j;
122 		}
123 		if (((u_char) c) != *fn) {
124 			if (c >= 'A' && c <= 'Z') {
125 				if (c + ('a' - 'A') != *fn) {
126 					if (*fn >= 'a' && *fn <= 'z')
127 						return *fn - ('a' - 'A') - c;
128 					else
129 						return *fn - c;
130 				}
131 			} else
132 				return *fn - c;
133 		}
134 		fn++;
135 	}
136 	if (isofn != isoend) {
137 		isofn += isochar(isofn, isoend, joliet_level, &c);
138 		switch (c) {
139 		default:
140 			return -1;
141 		case '.':
142 			if (isofn != isoend) {
143 				isochar(isofn, isoend, joliet_level, &c);
144 				if (c == ';')
145 					return 0;
146 			}
147 			return -1;
148 		case ';':
149 			return 0;
150 		}
151 	}
152 	return 0;
153 }
154 
155 /*
156  * translate a filename
157  */
158 void
159 isofntrans(infn, infnlen, outfn, outfnlen, original, casetrans, assoc, joliet_level)
160 	u_char *infn, *outfn;
161 	int infnlen;
162 	u_short *outfnlen;
163 	int original;
164 	int casetrans;
165 	int assoc;
166 	int joliet_level;
167 {
168 	int fnidx = 0;
169 	u_char *infnend = infn + infnlen;
170 
171 	if (assoc) {
172 		*outfn++ = ASSOCCHAR;
173 		fnidx++;
174 	}
175 	for (; infn != infnend; fnidx++) {
176 		char c;
177 
178 		infn += isochar(infn, infnend, joliet_level, &c);
179 
180 		if (casetrans && joliet_level == 0 && c >= 'A' && c <= 'Z')
181 			*outfn++ = c + ('a' - 'A');
182 		else if (!original && c == ';') {
183 			if (fnidx > 0 && outfn[-1] == '.')
184 				fnidx--;
185 			break;
186 		} else
187 			*outfn++ = c;
188 	}
189 	*outfnlen = fnidx;
190 }
191