Replace previous change by different test
[minix.git] / usr.sbin / installboot / minixfs3.c
blob1951b89bfc134f1119b7dc0a22e04c6611c92872
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <errno.h>
5 #include <sys/stat.h>
6 #include <sys/bootblock.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <string.h>
11 #include "installboot.h"
13 #ifndef DFL_SECSIZE
14 #define DFL_SECSIZE 512
15 #endif
17 #define MFS_FIRST_SUBP_OFFSET 32
19 static int minixfs3_read_mbr(const char* device, char* buf)
21 int fd;
22 int bytes;
23 int n;
25 fd = open(device, O_RDONLY);
26 if (fd == -1) {
27 fprintf(stderr, "Can't open %s: %s\n", device, strerror(errno));
28 return 1;
31 if (lseek(fd, MBR_PART_OFFSET, SEEK_SET) != MBR_PART_OFFSET) {
32 fprintf(stderr, "Can't seek in %s to %d: %s\n",
33 device, MBR_PART_OFFSET, strerror(errno));
34 close(fd);
35 return 1;
38 bytes = DFL_SECSIZE - MBR_PART_OFFSET;
40 if ((n = read(fd, buf, bytes)) != bytes) {
41 fprintf(stderr, "Can't read %d bytes from %s, %d read instead"
42 ": %s\n",
43 bytes, device, n, strerror(errno));
44 close(fd);
45 return 1;
48 if ((uint8_t)buf[bytes-2] != 0x55 || (uint8_t)buf[bytes-1] != 0xAA) {
49 fprintf(stderr, "No MBR on %s, signature is %x\n",
50 device, *(uint16_t*)(&buf[bytes-2]));
51 close(fd);
52 return 1;
55 close(fd);
56 return 0;
60 int minixfs3_is_minix_partition(const char* partition)
62 char buf[DFL_SECSIZE]; /* part table + signature */
63 int name_length = strlen(partition);
65 /* partition must be 0-3 */
66 if (atol(&partition[name_length-1]) >= 4) {
67 fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
68 partition);
69 return 0;
72 /* it should be partition device, not disk */
73 if (partition[name_length-2] != 'p') {
74 fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
75 partition);
76 return 0;
79 /* MINIX 3 partition with current scheme *must* have subpartitions,
80 * thus MBR has signature. minixfs3_read_mbr checks the signature.
82 if (minixfs3_read_mbr(partition, buf))
83 return 0;
84 return 1;
87 /* bootxx from NetBSD is ~8Kb, and old MINIX installations have just
88 * 1Kb of space for their bootblock. Check if there is enough space
89 * to install bootxx_minixfs3. New installation should have 16Kb before
90 * the first subpartition.
92 int minixfs3_has_bootblock_space(const char* partition)
94 char buf[DFL_SECSIZE]; /* part table + signature */
95 char disk[NAME_MAX];
96 struct mbr_partition *part;
97 uint32_t first_subpartition = (uint32_t) ~0;
98 uint32_t parent_partition = 0;
99 int i;
100 int name_length = strlen(partition);
102 /* partition must be 0-3 */
103 if (atol(&partition[name_length-1]) >= 4) {
104 fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
105 partition);
106 exit(1);
108 /* it should be partition device, not disk */
109 if (partition[name_length-2] != 'p') {
110 fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
111 partition);
112 exit(1);
115 if (minixfs3_read_mbr(partition, buf))
116 exit(1);
118 part = (struct mbr_partition *) buf;
120 for (i = 0; i < 4; i++) {
121 if (part[i].mbrp_size && part[i].mbrp_start < first_subpartition)
122 first_subpartition = part[i].mbrp_start;
125 strncpy(disk, partition, name_length - 2);
126 disk[name_length - 2] = '\0';
128 if (minixfs3_read_mbr(disk, buf))
129 exit(1);
131 for (i = 0; i < 4; i++) {
132 struct mbr_partition *p = &part[i];
133 if (p->mbrp_size && p->mbrp_start <= first_subpartition
134 && (p->mbrp_start + p->mbrp_size) > first_subpartition) {
135 parent_partition = p->mbrp_start;
136 break;
140 if ((first_subpartition - parent_partition) < MFS_FIRST_SUBP_OFFSET)
141 return 0;
142 else
143 return 1;