~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to libblkid/src/partitions/mac.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mac partitions parsing code
 
3
 *
 
4
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 
5
 *
 
6
 * This file may be redistributed under the terms of the
 
7
 * GNU Lesser General Public License.
 
8
 *
 
9
 */
 
10
#include <stdio.h>
 
11
#include <string.h>
 
12
#include <stdlib.h>
 
13
#include <stdint.h>
 
14
 
 
15
#include "partitions.h"
 
16
 
 
17
#define MAC_PARTITION_MAGIC             0x504d
 
18
#define MAC_PARTITION_MAGIC_OLD         0x5453
 
19
 
 
20
/*
 
21
 * Mac partition entry
 
22
 * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-126.html
 
23
 */
 
24
struct mac_partition {
 
25
        uint16_t        signature;      /* expected to be MAC_PARTITION_MAGIC */
 
26
        uint16_t        reserved;       /* reserved */
 
27
        uint32_t        map_count;      /* # blocks in partition map */
 
28
        uint32_t        start_block;    /* absolute starting block # of partition */
 
29
        uint32_t        block_count;    /* number of blocks in partition */
 
30
        char            name[32];       /* partition name */
 
31
        char            type[32];       /* string type description */
 
32
        uint32_t        data_start;     /* rel block # of first data block */
 
33
        uint32_t        data_count;     /* number of data blocks */
 
34
        uint32_t        status;         /* partition status bits */
 
35
        uint32_t        boot_start;     /* first logical block of boot code */
 
36
        uint32_t        boot_size;      /* size of boot code, in bytes */
 
37
        uint32_t        boot_load;      /* boot code load address */
 
38
        uint32_t        boot_load2;     /* reserved */
 
39
        uint32_t        boot_entry;     /* boot code entry point */
 
40
        uint32_t        boot_entry2;    /* reserved */
 
41
        uint32_t        boot_cksum;     /* boot code checksum */
 
42
        char            processor[16];  /* identifies ISA of boot */
 
43
 
 
44
        /* there is more stuff after this that we don't need */
 
45
} __attribute__((packed));
 
46
 
 
47
/*
 
48
 * Driver descriptor structure, in block 0
 
49
 * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-121.html
 
50
 */
 
51
struct mac_driver_desc {
 
52
        uint16_t        signature;      /* expected to be MAC_DRIVER_MAGIC */
 
53
        uint16_t        block_size;     /* block size of the device */
 
54
        uint32_t        block_count;    /* number of blocks on the device */
 
55
 
 
56
        /* there is more stuff after this that we don't need */
 
57
} __attribute__((packed));
 
58
 
 
59
static inline unsigned char *get_mac_block(
 
60
                                        blkid_probe pr,
 
61
                                        struct mac_driver_desc *md,
 
62
                                        uint32_t num)
 
63
{
 
64
        return blkid_probe_get_buffer(pr,
 
65
                        (blkid_loff_t) num * md->block_size, num);
 
66
}
 
67
 
 
68
static inline int has_part_signature(struct mac_partition *p)
 
69
{
 
70
        return  be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC ||
 
71
                be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC_OLD;
 
72
}
 
73
 
 
74
static int probe_mac_pt(blkid_probe pr,
 
75
                const struct blkid_idmag *mag __attribute__((__unused__)))
 
76
{
 
77
        struct mac_driver_desc *md;
 
78
        struct mac_partition *p;
 
79
        blkid_parttable tab = NULL;
 
80
        blkid_partlist ls;
 
81
        uint16_t ssf;   /* sector size fragment */
 
82
        uint32_t nblks, i;
 
83
 
 
84
 
 
85
        /* The driver descriptor record is always located at physical block 0,
 
86
         * the first block on the disk.
 
87
         */
 
88
        md = (struct mac_driver_desc *) blkid_probe_get_sector(pr, 0);
 
89
        if (!md)
 
90
                goto nothing;
 
91
 
 
92
 
 
93
        /* The partition map always begins at physical block 1,
 
94
         * the second block on the disk.
 
95
         */
 
96
        p = (struct mac_partition *) get_mac_block(pr, md, 1);
 
97
        if (!p)
 
98
                goto nothing;
 
99
 
 
100
        /* check the first partition signature */
 
101
        if (!has_part_signature(p))
 
102
                goto nothing;
 
103
 
 
104
        if (blkid_partitions_need_typeonly(pr))
 
105
                /* caller does not ask for details about partitions */
 
106
                return 0;
 
107
 
 
108
        ls = blkid_probe_get_partlist(pr);
 
109
        if (!ls)
 
110
                goto err;
 
111
 
 
112
        tab = blkid_partlist_new_parttable(ls, "mac", 0);
 
113
        if (!tab)
 
114
                goto err;
 
115
 
 
116
        ssf = md->block_size / 512;
 
117
        nblks = be32_to_cpu(p->map_count);
 
118
 
 
119
        for (i = 1; i <= nblks; ++i) {
 
120
                blkid_partition par;
 
121
                uint32_t start;
 
122
                uint32_t size;
 
123
 
 
124
                p = (struct mac_partition *) get_mac_block(pr, md, i);
 
125
                if (!p)
 
126
                        goto nothing;
 
127
                if (!has_part_signature(p))
 
128
                        goto nothing;
 
129
 
 
130
                if (be32_to_cpu(p->map_count) != nblks) {
 
131
                        DBG(DEBUG_LOWPROBE, printf(
 
132
                                "mac: inconsisten map_count in partition map, "
 
133
                                "entry[0]: %d, entry[%d]: %d\n",
 
134
                                nblks, i - 1,
 
135
                                be32_to_cpu(p->map_count)));
 
136
                }
 
137
 
 
138
                /*
 
139
                 * note that libparted ignores some mac partitions according to
 
140
                 * the partition name (e.g. "Apple_Free" or "Apple_Void"). We
 
141
                 * follows Linux kernel and all partitions are visible
 
142
                 */
 
143
 
 
144
                start = be32_to_cpu(p->start_block) * ssf;
 
145
                size = be32_to_cpu(p->block_count) * ssf;
 
146
 
 
147
                par = blkid_partlist_add_partition(ls, tab, start, size);
 
148
                if (!par)
 
149
                        goto err;
 
150
 
 
151
                blkid_partition_set_name(par, (unsigned char *) p->name,
 
152
                                                sizeof(p->name));
 
153
 
 
154
                blkid_partition_set_type_string(par, (unsigned char *) p->type,
 
155
                                                sizeof(p->type));
 
156
        }
 
157
 
 
158
        return 0;
 
159
 
 
160
nothing:
 
161
        return 1;
 
162
err:
 
163
        return -1;
 
164
}
 
165
 
 
166
/*
 
167
 * Mac disk always begin with "Driver Descriptor Record"
 
168
 * (struct mac_driver_desc) and magic 0x4552.
 
169
 */
 
170
const struct blkid_idinfo mac_pt_idinfo =
 
171
{
 
172
        .name           = "mac",
 
173
        .probefunc      = probe_mac_pt,
 
174
        .magics         =
 
175
        {
 
176
                /* big-endian magic string */
 
177
                { .magic = "\x45\x52", .len = 2 },
 
178
                { NULL }
 
179
        }
 
180
};
 
181