xref: /openbsd-src/sys/isofs/cd9660/cd9660_util.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: cd9660_util.c,v 1.5 1999/07/01 02:20:22 d Exp $	*/
2 /*	$NetBSD: cd9660_util.c,v 1.12 1997/01/24 00:27:33 cgd Exp $	*/
3 
4 /*-
5  * Copyright (c) 1994
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley
9  * by Pace Willisson (pace@blitz.com).  The Rock Ridge Extension
10  * Support code is derived from software contributed to Berkeley
11  * by Atsushi Murai (amurai@spec.co.jp). Joliet support was added by
12  * Joachim Kuebart (joki@kuebart.stuttgart.netsurf.de).
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. All advertising materials mentioning features or use of this software
23  *    must display the following acknowledgement:
24  *	This product includes software developed by the University of
25  *	California, Berkeley and its contributors.
26  * 4. Neither the name of the University nor the names of its contributors
27  *    may be used to endorse or promote products derived from this software
28  *    without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  *	@(#)cd9660_util.c	8.3 (Berkeley) 12/5/94
43  */
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/namei.h>
48 #include <sys/resourcevar.h>
49 #include <sys/kernel.h>
50 #include <sys/file.h>
51 #include <sys/stat.h>
52 #include <sys/buf.h>
53 #include <sys/proc.h>
54 #include <sys/conf.h>
55 #include <sys/mount.h>
56 #include <sys/vnode.h>
57 #include <sys/malloc.h>
58 #include <sys/dirent.h>
59 
60 #include <isofs/cd9660/iso.h>
61 #include <isofs/cd9660/cd9660_extern.h>
62 
63 /*
64  * Get one character out of an iso filename
65  * Obey joliet_level
66  * Return number of bytes consumed
67  */
68 int
69 isochar(isofn, isoend, joliet_level, c)
70       const u_char *isofn;
71       const u_char *isoend;
72       int joliet_level;
73       u_char *c;
74 {
75       *c = *isofn++;
76       if (joliet_level == 0 || isofn == isoend)
77               /* (00) and (01) are one byte in Joliet, too */
78               return 1;
79 
80       /* No Unicode support yet :-( */
81       switch (*c) {
82       default:
83               *c = '?';
84               break;
85       case '\0':
86               *c = *isofn;
87               break;
88       }
89       return 2;
90 }
91 
92 /*
93  * translate and compare a filename
94  * returns (fn - isofn)
95  * Note: Version number plus ';' may be omitted.
96  */
97 int
98 isofncmp(fn, fnlen, isofn, isolen, joliet_level)
99 	const u_char *fn, *isofn;
100 	int fnlen, isolen, joliet_level;
101 {
102 	int i, j;
103 	u_char c;
104 	const u_char *fnend = fn + fnlen, *isoend = isofn + isolen;
105 
106 	for (; fn != fnend; fn++) {
107 		if (isofn == isoend)
108 			return *fn;
109 		isofn += isochar(isofn, isoend, joliet_level, &c);
110 		if (c == ';') {
111 			if (*fn++ != ';')
112 				return fn[-1];
113 			for (i = 0; fn != fnend; 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 	}
135 	if (isofn != isoend) {
136 		isofn += isochar(isofn, isoend, joliet_level, &c);
137 		switch (c) {
138 		default:
139 			return -c;
140 		case '.':
141 			if (isofn != isoend) {
142 				isochar(isofn, isoend, joliet_level, &c);
143 				if (c == ';')
144 					return 0;
145 			}
146 			return -1;
147 		case ';':
148 			return 0;
149 		}
150 	}
151 	return 0;
152 }
153 
154 /*
155  * translate a filename of length > 0
156  */
157 void
158 isofntrans(infn, infnlen, outfn, outfnlen, original, assoc, joliet_level)
159 	u_char *infn, *outfn;
160 	int infnlen;
161 	u_short *outfnlen;
162 	int original;
163 	int assoc;
164 	int joliet_level;
165 {
166 	int fnidx = 0;
167 	u_char c, d = '\0', *infnend = infn + infnlen;
168 
169 	if (assoc) {
170 		*outfn++ = ASSOCCHAR;
171 		fnidx++;
172 	}
173 	for (; infn != infnend; fnidx++) {
174 		infn += isochar(infn, infnend, joliet_level, &c);
175 
176 		if (!original && c == ';') {
177 			fnidx -= (d == '.');
178 			break;
179 		} else
180 			*outfn++ = c;
181 		d = c;
182 	}
183 	*outfnlen = fnidx;
184 }
185