Drop main() prototype. Syncs with NetBSD-8
[minix.git] / usr.sbin / installboot / minixfs3.c
blobf590c0cef17523657a8c0556e64548a823e16489
1 #if HAVE_NBTOOL_CONFIG_H
2 #include "nbtool_config.h"
3 #endif
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <sys/stat.h>
10 #include <limits.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <string.h>
15 #include "installboot.h"
17 #ifndef DFL_SECSIZE
18 #define DFL_SECSIZE 512
19 #endif
21 #define MFS_FIRST_SUBP_OFFSET 32
23 enum {
24 TYPE_BAD,
25 TYPE_PART,
26 TYPE_DISK
29 static int
30 minixfs3_read_mbr(const char* device, char* buf)
32 int fd;
33 int bytes;
34 int n;
36 fd = open(device, O_RDONLY);
37 if (fd == -1) {
38 fprintf(stderr, "Can't open %s: %s\n", device, strerror(errno));
39 return 1;
42 if (lseek(fd, MBR_PART_OFFSET, SEEK_SET) != MBR_PART_OFFSET) {
43 fprintf(stderr, "Can't seek in %s to %d: %s\n",
44 device, MBR_PART_OFFSET, strerror(errno));
45 close(fd);
46 return 1;
49 bytes = DFL_SECSIZE - MBR_PART_OFFSET;
51 if ((n = read(fd, buf, bytes)) != bytes) {
52 fprintf(stderr, "Can't read %d bytes from %s, %d read instead"
53 ": %s\n",
54 bytes, device, n, strerror(errno));
55 close(fd);
56 return 1;
59 if ((uint8_t)buf[bytes-2] != 0x55 || (uint8_t)buf[bytes-1] != 0xAA) {
60 fprintf(stderr, "No MBR on %s, signature is %x\n",
61 device, *(uint16_t*)(&buf[bytes-2]));
62 close(fd);
63 return 1;
66 close(fd);
67 return 0;
70 static int
71 minixfs3_get_dev_type(const char *device, ib_params *params)
73 int len, type;
76 * Unless the -f flag is given, we expect to be provided with a primary
77 * partition. That is, a device name that ends with "pN", N being 0-3.
78 * If the -f flag is given, we assume that anything else is a whole
79 * disk. If we were given a subpartition, it will fail the subsequent
80 * MBR signature test, so we need not check this explicitly.
82 len = strlen(device);
84 if (len > 2 && device[len-2] == 'p' &&
85 (unsigned) (device[len-1] - '0') <= 3) {
86 type = TYPE_PART;
87 } else {
88 type = TYPE_DISK;
91 if (type != TYPE_PART && !(params->flags & IB_FORCE)) {
92 fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
93 device);
94 return TYPE_BAD;
97 return type;
101 minixfs3_is_minix_partition(ib_params *params)
103 char buf[DFL_SECSIZE]; /* part table + signature */
105 if (minixfs3_get_dev_type(params->filesystem, params) == TYPE_BAD)
106 return 0;
108 /* MINIX 3 partition with current scheme *must* have subpartitions,
109 * thus MBR has signature. minixfs3_read_mbr checks the signature.
111 if (minixfs3_read_mbr(params->filesystem, buf))
112 return 0;
113 return 1;
116 /* bootxx from NetBSD is ~8Kb, and old MINIX installations have just
117 * 1Kb of space for their bootblock. Check if there is enough space
118 * to install bootxx_minixfs3. New installation should have 16Kb before
119 * the first subpartition.
122 minixfs3_has_bootblock_space(ib_params *params)
124 const char *device;
125 char buf[DFL_SECSIZE]; /* part table + signature */
126 char parent_name[NAME_MAX];
127 struct mbr_partition *part;
128 uint32_t first_subpartition = (uint32_t) ~0;
129 uint32_t parent_partition;
130 int i, len, type = 0;
132 device = params->filesystem;
134 if ((type = minixfs3_get_dev_type(device, params)) == TYPE_BAD)
135 exit(1);
137 if (minixfs3_read_mbr(device, buf))
138 exit(1);
140 part = (struct mbr_partition *) buf;
142 for (i = 0; i < 4; i++) {
143 if (part[i].mbrp_size &&
144 part[i].mbrp_start < first_subpartition)
145 first_subpartition = part[i].mbrp_start;
148 if (type == TYPE_PART) {
149 /* The target is a partition. Look up its starting offset. */
150 len = strlen(device);
151 strncpy(parent_name, device, len - 2);
152 parent_name[len - 2] = '\0';
154 if (minixfs3_read_mbr(parent_name, buf))
155 exit(1);
157 parent_partition = 0;
158 for (i = 0; i < 4; i++) {
159 struct mbr_partition *p = &part[i];
160 if (p->mbrp_size && p->mbrp_start <= first_subpartition
161 && (p->mbrp_start + p->mbrp_size) >
162 first_subpartition) {
163 parent_partition = p->mbrp_start;
164 break;
167 } else {
168 /* The target is a whole disk. The starting offset is 0. */
169 parent_partition = 0;
172 if ((first_subpartition - parent_partition) < MFS_FIRST_SUBP_OFFSET)
173 return 0;
174 else
175 return 1;