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

« back to all changes in this revision

Viewing changes to partx/dos.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-06-20 22:31:50 UTC
  • mfrom: (1.6.3 upstream) (4.5.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110620223150-lz8wrv0946ihcz3z
Tags: 2.19.1-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Build for multiarch.
  - Add pre-depends on multiarch-support.
  - configure.ac: don't try to be clever about extracting a path name from
    $libdir to append to /usr in a way that's not overridable; instead,
    reuse the built-in configurable libexecdir.
  - Fix up the .pc.in files to know about libexecdir, so our substitutions
    don't leave us with unusable pkg-config files.
  - Install custom blkid.conf to use /dev/.blkid.tab since we don't
    expect device names to survive a reboot
  - Mention mountall(8) in fstab(5) manpages, along with its special
    options.
  - Since upstart is required in Ubuntu, the hwclock.sh init script is not
    called on startup and the hwclockfirst.sh init script is removed.
  - Drop depends on initscripts for the above.
  - Replace hwclock udev rule with an Upstart job.
  - For the case where mount is called with a directory to mount, look
    that directory up in mountall's /lib/init/fstab if we couldn't find
    it mentioned anywhere else.  This means "mount /proc", "mount /sys",
    etc. work.
  - mount.8 points to the cifs-utils package, not the obsolete smbfs one. 
* Dropped changes:
  - mount.preinst: lsb_release has been fixed in lucid and above to be
    usable without configuration, so we don't have to diverge from Debian
    here anymore.
* Changes merged upstream:
  - sfdisk support for '+' with '-N'
  - mount/umount.c: fix a segfault on umount with empty mtab entry
  - Fix arbitrary unmount with fuse security issue

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdio.h>
2
 
 
3
 
#include "blkdev.h"
4
 
 
5
 
#include "partx.h"
6
 
#include "dos.h"
7
 
 
8
 
static int
9
 
is_extended(int type) {
10
 
        return (type == 5 || type == 0xf || type == 0x85);
11
 
}
12
 
 
13
 
/* assemble badly aligned little endian integer */
14
 
static inline unsigned int
15
 
assemble4le(unsigned char *p) {
16
 
        return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
17
 
}
18
 
 
19
 
static inline unsigned int
20
 
partition_start(struct partition *p) {
21
 
        return assemble4le(&(p->start_sect[0]));
22
 
}
23
 
 
24
 
static inline unsigned int
25
 
partition_size(struct partition *p) {
26
 
        return assemble4le(&(p->nr_sects[0]));
27
 
}
28
 
 
29
 
static int
30
 
read_extended_partition(int fd, struct partition *ep,
31
 
                        struct slice *sp, int ns, int ssf)
32
 
{
33
 
        struct partition *p;
34
 
        unsigned long start, here;
35
 
        unsigned char *bp;
36
 
        int loopct = 0;
37
 
        int moretodo = 1;
38
 
        int i, n=0;
39
 
 
40
 
        here = start = partition_start(ep);;
41
 
 
42
 
        while (moretodo) {
43
 
                moretodo = 0;
44
 
                if (++loopct > 100)
45
 
                        return n;
46
 
 
47
 
                bp = getblock(fd, here * ssf);  /* in 512 blocks */
48
 
                if (bp == NULL)
49
 
                        return n;
50
 
 
51
 
                if (bp[510] != 0x55 || bp[511] != 0xaa)
52
 
                        return n;
53
 
 
54
 
                p = (struct partition *) (bp + 0x1be);
55
 
 
56
 
                for (i=0; i<2; i++, p++) {
57
 
                        if (partition_size(p) == 0 || is_extended(p->sys_type))
58
 
                                continue;
59
 
                        if (n < ns) {
60
 
                                sp[n].start = (here + partition_start(p)) * ssf;
61
 
                                sp[n].size = partition_size(p) * ssf;
62
 
                                n++;
63
 
                        } else {
64
 
                                fprintf(stderr,
65
 
                                    "dos_extd_partition: too many slices\n");
66
 
                                return n;
67
 
                        }
68
 
                        loopct = 0;
69
 
                }
70
 
 
71
 
                p -= 2;
72
 
                for (i=0; i<2; i++, p++) {
73
 
                        if (partition_size(p) != 0 &&
74
 
                            is_extended(p->sys_type)) {
75
 
                                here = start + partition_start(p);
76
 
                                moretodo = 1;
77
 
                                break;
78
 
                        }
79
 
                }
80
 
        }
81
 
        return n;
82
 
}
83
 
 
84
 
static int
85
 
is_gpt(int type) {
86
 
        return (type == 0xEE);
87
 
}
88
 
 
89
 
int
90
 
read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) {
91
 
        struct partition *p;
92
 
        unsigned long offset = all.start;
93
 
        int i, n=0;
94
 
        unsigned char *bp;
95
 
        int ssf;
96
 
 
97
 
        bp = getblock(fd, offset);
98
 
        if (bp == NULL)
99
 
                return -1;
100
 
 
101
 
        if (bp[510] != 0x55 || bp[511] != 0xaa)
102
 
                return -1;
103
 
 
104
 
        /* msdos PT depends sector size... */
105
 
        if (blkdev_get_sector_size(fd, &ssf) != 0)
106
 
                ssf = DEFAULT_SECTOR_SIZE;
107
 
 
108
 
        /* ... but partx counts everything in 512-byte sectors */
109
 
        ssf /= 512;
110
 
 
111
 
        p = (struct partition *) (bp + 0x1be);
112
 
        for (i=0; i<4; i++) {
113
 
                if (is_gpt(p->sys_type))
114
 
                        return 0;
115
 
                p++;
116
 
        }
117
 
        p = (struct partition *) (bp + 0x1be);
118
 
        for (i=0; i<4; i++) {
119
 
                /* always add, even if zero length */
120
 
                if (n < ns) {
121
 
                        sp[n].start = partition_start(p) * ssf;
122
 
                        sp[n].size = partition_size(p) * ssf;
123
 
                        n++;
124
 
                } else {
125
 
                        fprintf(stderr,
126
 
                                "dos_partition: too many slices\n");
127
 
                        break;
128
 
                }
129
 
                p++;
130
 
        }
131
 
        p = (struct partition *) (bp + 0x1be);
132
 
        for (i=0; i<4; i++) {
133
 
                if (is_extended(p->sys_type))
134
 
                        n += read_extended_partition(fd, p, sp+n, ns-n, ssf);
135
 
                p++;
136
 
        }
137
 
        return n;
138
 
}