No empty .Rs/.Re
[netbsd-mini2440.git] / distrib / cdrom / macppc_installboot / cd9660.c
blob15381da5bb0e848dc41ed3b9ca057c794e18c3ea
1 /* $NetBSD: cd9660.c,v 1.2 2008/02/27 13:08:52 tsutsui Exp $ */
3 /*-
4 * Copyright (c) 2005 Izumi Tsutsui. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #if HAVE_NBTOOL_CONFIG_H
28 #include "nbtool_config.h"
29 #endif
31 #include <sys/cdefs.h>
32 #if defined(__RCSID) && !defined(__lint)
33 __RCSID("$NetBSD: cd9660.c,v 1.2 2008/02/27 13:08:52 tsutsui Exp $");
34 #endif /* !__lint */
36 #include <sys/param.h>
37 #include <sys/dirent.h>
39 #if !HAVE_NBTOOL_CONFIG_H
40 #include <sys/mount.h>
41 #endif
43 #include <assert.h>
44 #include <err.h>
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <stdarg.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
53 #include <fs/cd9660/iso.h>
55 #include "installboot.h"
57 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
58 #define MAXLEN 16
61 int
62 cd9660_match(ib_params *params)
64 int rv, blocksize;
65 struct iso_primary_descriptor ipd;
67 assert(params != NULL);
68 assert(params->fstype != NULL);
69 assert(params->fsfd != -1);
71 rv = pread(params->fsfd, &ipd, sizeof(ipd),
72 ISO_DEFAULT_BLOCK_SIZE * 16);
73 if (rv == -1) {
74 warn("Reading primary descriptor in `%s'", params->filesystem);
75 return 0;
76 } else if (rv != sizeof(ipd)) {
77 warnx("Reading primary descriptor in `%s': short read",
78 params->filesystem);
79 return 0;
82 if (ipd.type[0] != ISO_VD_PRIMARY ||
83 strncmp(ipd.id, ISO_STANDARD_ID, sizeof(ipd.id)) != 0 ||
84 ipd.version[0] != 1) {
85 warnx("Filesystem `%s' is not ISO9660 format",
86 params->filesystem);
87 return 0;
90 blocksize = isonum_723((char *)ipd.logical_block_size);
91 if (blocksize != ISO_DEFAULT_BLOCK_SIZE) {
92 warnx("Invalid blocksize %d in `%s'",
93 blocksize, params->filesystem);
94 return 0;
97 params->fstype->blocksize = blocksize;
98 params->fstype->needswap = 0;
100 return 1;
104 cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
106 uint8_t buf[ISO_DEFAULT_BLOCK_SIZE];
107 char name[MAXNAMLEN];
108 char *ofwboot;
109 off_t loc;
110 int rv, blocksize, found, i;
111 struct iso_primary_descriptor ipd;
112 struct iso_directory_record *idr;
114 assert(params != NULL);
115 assert(params->stage2 != NULL);
116 assert(maxblk != NULL);
117 assert(blocks != NULL);
119 #if 0
120 if (params->flags & IB_STAGE2START)
121 return hardcode_stage2(params, maxblk, blocks);
122 #endif
124 /* The secondary bootstrap must be clearly in /. */
125 strlcpy(name, params->stage2, MAXNAMLEN);
126 ofwboot = name;
127 if (ofwboot[0] == '/')
128 ofwboot++;
129 if (strchr(ofwboot, '/') != NULL) {
130 warnx("The secondary bootstrap `%s' must be in / "
131 "on filesystem `%s'", params->stage2, params->filesystem);
132 return 0;
134 if (strchr(ofwboot, '.') == NULL) {
136 * XXX should fix isofncmp()?
138 strlcat(ofwboot, ".", MAXNAMLEN);
141 rv = pread(params->fsfd, &ipd, sizeof(ipd),
142 ISO_DEFAULT_BLOCK_SIZE * 16);
143 if (rv == -1) {
144 warn("Reading primary descriptor in `%s'", params->filesystem);
145 return 0;
146 } else if (rv != sizeof(ipd)) {
147 warnx("Reading primary descriptor in `%s': short read",
148 params->filesystem);
149 return 0;
151 blocksize = isonum_723((char *)ipd.logical_block_size);
153 idr = (void *)ipd.root_directory_record;
154 loc = (off_t)isonum_733(idr->extent) * blocksize;
155 rv = pread(params->fsfd, buf, blocksize, loc);
156 if (rv == -1) {
157 warn("Reading root directory record in `%s'",
158 params->filesystem);
159 return 0;
160 } else if (rv != sizeof(ipd)) {
161 warnx("Reading root directory record in `%s': short read",
162 params->filesystem);
163 return 0;
166 found = 0;
167 for (i = 0; i < blocksize - sizeof(struct iso_directory_record);
168 i += (u_char)idr->length[0]) {
169 idr = (void *)&buf[i];
171 #ifdef DEBUG
172 printf("i = %d, idr->length[0] = %3d\n",
173 i, (u_char)idr->length[0]);
174 #endif
175 /* check end of entries */
176 if (idr->length[0] == 0) {
177 #ifdef DEBUG
178 printf("end of entries\n");
179 #endif
180 break;
183 if (idr->flags[0] & 2) {
184 /* skip directory entries */
185 #ifdef DEBUG
186 printf("skip directory entry\n");
187 #endif
188 continue;
190 if (idr->name_len[0] == 1 &&
191 (idr->name[0] == 0 || idr->name[0] == 1)) {
192 /* skip "." and ".." */
193 #ifdef DEBUG
194 printf("skip dot dot\n");
195 #endif
196 continue;
198 #ifdef DEBUG
200 int j;
202 printf("filename:");
203 for (j = 0; j < isonum_711(idr->name_len); j++)
204 printf("%c", idr->name[j]);
205 printf("\n");
207 #endif
208 if (isofncmp(ofwboot, strlen(ofwboot),
209 idr->name, isonum_711(idr->name_len), 0) == 0) {
210 found = 1;
211 /* ISO filesystem always has contiguous file blocks */
212 blocks[0].block = (int64_t)isonum_733(idr->extent);
213 /* XXX bootxx assumes blocksize is 512 */
214 blocks[0].block *= blocksize / 512;
215 blocks[0].blocksize =
216 roundup(isonum_733(idr->size), blocksize);
217 *maxblk = 1;
218 #ifdef DEBUG
219 printf("block = %ld, blocksize = %ld\n",
220 (long)blocks[0].block, blocks[0].blocksize);
221 #endif
222 break;
226 if (found == 0) {
227 warnx("Can't find secondary bootstrap `%s' in filesystem `%s'",
228 params->stage2, params->filesystem);
229 return 0;
232 return 1;