Update man page for multipath -r
[platform/upstream/multipath-tools.git] / kpartx / dos.c
1 /*
2  * Source: copy of util-linux' partx dos.c
3  *
4  * Copyrights of the original file apply 
5  * Copyright (c) 2005 Bastian Blank
6  */
7 #include "kpartx.h"
8 #include "byteorder.h"
9 #include <stdio.h>
10 #include <string.h>
11 #include "dos.h"
12
13 static int
14 is_extended(int type) {
15         return (type == 5 || type == 0xf || type == 0x85);
16 }
17
18 static int
19 read_extended_partition(int fd, struct partition *ep, int en,
20                         struct slice *sp, int ns)
21 {
22         struct partition p;
23         unsigned long start, here, next;
24         unsigned char *bp;
25         int loopct = 0;
26         int moretodo = 1;
27         int i, n=0;
28
29         next = start = le32_to_cpu(ep->start_sect);
30
31         while (moretodo) {
32                 here = next;
33                 moretodo = 0;
34                 if (++loopct > 100)
35                         return n;
36
37                 bp = (unsigned char *)getblock(fd, here);
38                 if (bp == NULL)
39                         return n;
40
41                 if (bp[510] != 0x55 || bp[511] != 0xaa)
42                         return n;
43
44                 for (i=0; i<2; i++) {
45                         memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p));
46                         if (is_extended(p.sys_type)) {
47                                 if (p.nr_sects && !moretodo) {
48                                         next = start + le32_to_cpu(p.start_sect);
49                                         moretodo = 1;
50                                 }
51                                 continue;
52                         }
53                         if (n < ns) {
54                                 sp[n].start = here + le32_to_cpu(p.start_sect);
55                                 sp[n].size = le32_to_cpu(p.nr_sects);
56                                 sp[n].container = en + 1;
57                                 n++;
58                         } else {
59                                 fprintf(stderr,
60                                     "dos_extd_partition: too many slices\n");
61                                 return n;
62                         }
63                         loopct = 0;
64                 }
65         }
66         return n;
67 }
68
69 static int
70 is_gpt(int type) {
71         return (type == 0xEE);
72 }
73
74 int
75 read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) {
76         struct partition p;
77         unsigned long offset = all.start;
78         int i, n=4;
79         unsigned char *bp;
80
81         bp = (unsigned char *)getblock(fd, offset);
82         if (bp == NULL)
83                 return -1;
84
85         if (bp[510] != 0x55 || bp[511] != 0xaa)
86                 return -1;
87
88         for (i=0; i<4; i++) {
89                 memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p));
90                 if (is_gpt(p.sys_type))
91                         return 0;
92                 if (i < ns) {
93                         sp[i].start =  le32_to_cpu(p.start_sect);
94                         sp[i].size = le32_to_cpu(p.nr_sects);
95                 } else {
96                         fprintf(stderr,
97                                 "dos_partition: too many slices\n");
98                         break;
99                 }
100                 if (is_extended(p.sys_type)) {
101                         n += read_extended_partition(fd, &p, i, sp+n, ns-n);
102                 }
103         }
104         return n;
105 }