1 /* $NetBSD: cd9660.c,v 1.2 2008/02/27 13:08:52 tsutsui Exp $ */
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
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"
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 $");
36 #include <sys/param.h>
37 #include <sys/dirent.h>
39 #if !HAVE_NBTOOL_CONFIG_H
40 #include <sys/mount.h>
53 #include <fs/cd9660/iso.h>
55 #include "installboot.h"
57 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
62 cd9660_match(ib_params
*params
)
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);
74 warn("Reading primary descriptor in `%s'", params
->filesystem
);
76 } else if (rv
!= sizeof(ipd
)) {
77 warnx("Reading primary descriptor in `%s': short read",
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",
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
);
97 params
->fstype
->blocksize
= blocksize
;
98 params
->fstype
->needswap
= 0;
104 cd9660_findstage2(ib_params
*params
, uint32_t *maxblk
, ib_block
*blocks
)
106 uint8_t buf
[ISO_DEFAULT_BLOCK_SIZE
];
107 char name
[MAXNAMLEN
];
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
);
120 if (params
->flags
& IB_STAGE2START
)
121 return hardcode_stage2(params
, maxblk
, blocks
);
124 /* The secondary bootstrap must be clearly in /. */
125 strlcpy(name
, params
->stage2
, MAXNAMLEN
);
127 if (ofwboot
[0] == '/')
129 if (strchr(ofwboot
, '/') != NULL
) {
130 warnx("The secondary bootstrap `%s' must be in / "
131 "on filesystem `%s'", params
->stage2
, params
->filesystem
);
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);
144 warn("Reading primary descriptor in `%s'", params
->filesystem
);
146 } else if (rv
!= sizeof(ipd
)) {
147 warnx("Reading primary descriptor in `%s': short read",
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
);
157 warn("Reading root directory record in `%s'",
160 } else if (rv
!= sizeof(ipd
)) {
161 warnx("Reading root directory record in `%s': short read",
167 for (i
= 0; i
< blocksize
- sizeof(struct iso_directory_record
);
168 i
+= (u_char
)idr
->length
[0]) {
169 idr
= (void *)&buf
[i
];
172 printf("i = %d, idr->length[0] = %3d\n",
173 i
, (u_char
)idr
->length
[0]);
175 /* check end of entries */
176 if (idr
->length
[0] == 0) {
178 printf("end of entries\n");
183 if (idr
->flags
[0] & 2) {
184 /* skip directory entries */
186 printf("skip directory entry\n");
190 if (idr
->name_len
[0] == 1 &&
191 (idr
->name
[0] == 0 || idr
->name
[0] == 1)) {
192 /* skip "." and ".." */
194 printf("skip dot dot\n");
203 for (j
= 0; j
< isonum_711(idr
->name_len
); j
++)
204 printf("%c", idr
->name
[j
]);
208 if (isofncmp(ofwboot
, strlen(ofwboot
),
209 idr
->name
, isonum_711(idr
->name_len
), 0) == 0) {
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
);
219 printf("block = %ld, blocksize = %ld\n",
220 (long)blocks
[0].block
, blocks
[0].blocksize
);
227 warnx("Can't find secondary bootstrap `%s' in filesystem `%s'",
228 params
->stage2
, params
->filesystem
);