#define MFS_FIRST_SUBP_OFFSET 32
-static int minixfs3_read_mbr(const char* device, char* buf)
+enum {
+ TYPE_BAD,
+ TYPE_PART,
+ TYPE_DISK
+};
+
+static int
+minixfs3_read_mbr(const char* device, char* buf)
{
int fd;
int bytes;
return 0;
}
-
-int minixfs3_is_minix_partition(const char* partition)
+static int
+minixfs3_get_dev_type(const char *device, ib_params *params)
{
- char buf[DFL_SECSIZE]; /* part table + signature */
- int name_length = strlen(partition);
+ int len, type;
+
+ /*
+ * Unless the -f flag is given, we expect to be provided with a primary
+ * partition. That is, a device name that ends with "pN", N being 0-3.
+ * If the -f flag is given, we assume that anything else is a whole
+ * disk. If we were given a subpartition, it will fail the subsequent
+ * MBR signature test, so we need not check this explicitly.
+ */
+ len = strlen(device);
- /* partition must be 0-3 */
- if (atol(&partition[name_length-1]) >= 4) {
- fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
- partition);
- return 0;
+ if (len > 2 && device[len-2] == 'p' &&
+ (unsigned) (device[len-1] - '0') <= 3) {
+ type = TYPE_PART;
+ } else {
+ type = TYPE_DISK;
}
- /* it should be partition device, not disk */
- if (partition[name_length-2] != 'p') {
+ if (type != TYPE_PART && !(params->flags & IB_FORCE)) {
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
- partition);
- return 0;
+ device);
+ return TYPE_BAD;
}
+ return type;
+}
+
+int
+minixfs3_is_minix_partition(ib_params *params)
+{
+ char buf[DFL_SECSIZE]; /* part table + signature */
+
+ if (minixfs3_get_dev_type(params->filesystem, params) == TYPE_BAD)
+ return 0;
+
/* MINIX 3 partition with current scheme *must* have subpartitions,
* thus MBR has signature. minixfs3_read_mbr checks the signature.
*/
- if (minixfs3_read_mbr(partition, buf))
+ if (minixfs3_read_mbr(params->filesystem, buf))
return 0;
return 1;
}
* to install bootxx_minixfs3. New installation should have 16Kb before
* the first subpartition.
*/
-int minixfs3_has_bootblock_space(const char* partition)
+int
+minixfs3_has_bootblock_space(ib_params *params)
{
+ const char *device;
char buf[DFL_SECSIZE]; /* part table + signature */
- char disk[NAME_MAX];
+ char parent_name[NAME_MAX];
struct mbr_partition *part;
uint32_t first_subpartition = (uint32_t) ~0;
- uint32_t parent_partition = 0;
- int i;
- int name_length = strlen(partition);
+ uint32_t parent_partition;
+ int i, len, type = 0;
- /* partition must be 0-3 */
- if (atol(&partition[name_length-1]) >= 4) {
- fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
- partition);
- exit(1);
- }
- /* it should be partition device, not disk */
- if (partition[name_length-2] != 'p') {
- fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
- partition);
+ device = params->filesystem;
+
+ if ((type = minixfs3_get_dev_type(device, params)) == TYPE_BAD)
exit(1);
- }
- if (minixfs3_read_mbr(partition, buf))
+ if (minixfs3_read_mbr(device, buf))
exit(1);
part = (struct mbr_partition *) buf;
for (i = 0; i < 4; i++) {
- if (part[i].mbrp_size && part[i].mbrp_start < first_subpartition)
+ if (part[i].mbrp_size &&
+ part[i].mbrp_start < first_subpartition)
first_subpartition = part[i].mbrp_start;
}
- strncpy(disk, partition, name_length - 2);
- disk[name_length - 2] = '\0';
-
- if (minixfs3_read_mbr(disk, buf))
- exit(1);
-
- for (i = 0; i < 4; i++) {
- struct mbr_partition *p = &part[i];
- if (p->mbrp_size && p->mbrp_start <= first_subpartition
- && (p->mbrp_start + p->mbrp_size) > first_subpartition) {
- parent_partition = p->mbrp_start;
- break;
+ if (type == TYPE_PART) {
+ /* The target is a partition. Look up its starting offset. */
+ len = strlen(device);
+ strncpy(parent_name, device, len - 2);
+ parent_name[len - 2] = '\0';
+
+ if (minixfs3_read_mbr(parent_name, buf))
+ exit(1);
+
+ parent_partition = 0;
+ for (i = 0; i < 4; i++) {
+ struct mbr_partition *p = &part[i];
+ if (p->mbrp_size && p->mbrp_start <= first_subpartition
+ && (p->mbrp_start + p->mbrp_size) >
+ first_subpartition) {
+ parent_partition = p->mbrp_start;
+ break;
+ }
}
+ } else {
+ /* The target is a whole disk. The starting offset is 0. */
+ parent_partition = 0;
}
if ((first_subpartition - parent_partition) < MFS_FIRST_SUBP_OFFSET)