1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/* Sun style partitioning */
#include <fcntl.h>
#include <unistd.h>
#include "balkan.h"
#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
#define BSD_MAXPARTITIONS 8
#define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */
#define BSD_LABEL_OFFSET 64
struct bsd_disklabel {
unsigned int d_magic; /* the magic number */
signed short d_type; /* drive type */
signed short d_subtype; /* controller/d_type specific */
char d_typename[16]; /* type name, e.g. "eagle" */
char d_packname[16]; /* pack identifier */
unsigned int d_secsize; /* # of bytes per sector */
unsigned int d_nsectors; /* # of data sectors per track */
unsigned int d_ntracks; /* # of tracks per cylinder */
unsigned int d_ncylinders; /* # of data cylinders per unit */
unsigned int d_secpercyl; /* # of data sectors per cylinder */
unsigned int d_secperunit; /* # of data sectors per unit */
unsigned short d_sparespertrack; /* # of spare sectors per track */
unsigned short d_sparespercyl; /* # of spare sectors per cylinder */
unsigned int d_acylinders; /* # of alt. cylinders per unit */
unsigned short d_rpm; /* rotational speed */
unsigned short d_interleave; /* hardware sector interleave */
unsigned short d_trackskew; /* sector 0 skew, per track */
unsigned short d_cylskew; /* sector 0 skew, per cylinder */
unsigned int d_headswitch; /* head switch time, usec */
unsigned int d_trkseek; /* track-to-track seek, usec */
unsigned int d_flags; /* generic flags */
#define NDDATA 5
unsigned int d_drivedata[NDDATA]; /* drive-type specific information */
#define NSPARE 5
unsigned int d_spare[NSPARE]; /* reserved for future use */
unsigned int d_magic2; /* the magic number (again) */
unsigned short d_checksum; /* xor of data incl. partitions */
/* filesystem and partition information: */
unsigned short d_npartitions; /* number of partitions in following */
unsigned int d_bbsize; /* size of boot area at sn0, bytes */
unsigned int d_sbsize; /* max size of fs superblock, bytes */
struct bsd_partition { /* the partition table */
unsigned int p_size; /* number of sectors in partition */
unsigned int p_offset; /* starting sector */
unsigned int p_fsize; /* filesystem basic fragment size */
unsigned char p_fstype; /* filesystem type, see below */
unsigned char p_frag; /* filesystem fragments per block */
unsigned short p_cpg; /* filesystem cylinders per group */
} d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
};
long long llseek(int fd, long long offset, int whence);
#if 0
static unsigned short xbsd_dkcksum (struct bsd_disklabel *lp) {
unsigned short *start, *end;
unsigned short sum = 0;
lp->d_checksum = 0;
start = (u_short *)lp;
end = (u_short *)&lp->d_partitions[lp->d_npartitions];
while (start < end)
sum ^= *start++;
return (sum);
}
#endif
int bsdlReadTable(int fd, struct partitionTable * table) {
struct bsd_disklabel label;
int i, rc;
unsigned short *p, csum;
int s;
table->maxNumPartitions = 8;
for (i = 0; i < table->maxNumPartitions; i++)
table->parts[i].type = -1;
table->sectorSize = 512;
if (lseek(fd, BSD_LABEL_OFFSET, SEEK_SET) < 0)
return BALKAN_ERROR_ERRNO;
if (read(fd, &label, sizeof(label)) != sizeof(label))
return BALKAN_ERROR_ERRNO;
if (label.d_magic != BSD_DISKMAGIC)
return BALKAN_ERROR_BADMAGIC;
#if 0
/* minlabel doens't write checksums :-( */
if (xbsd_dkcksum(&label))
return BALKAN_ERROR_BADMAGIC;
#endif
if (label.d_npartitions > 8)
label.d_npartitions = 8;
for (i = 0; i < label.d_npartitions; i++) {
if (label.d_partitions[i].p_size && label.d_partitions[i].p_fstype) {
table->parts[i].startSector = label.d_partitions[i].p_offset;
table->parts[i].size = label.d_partitions[i].p_size;
switch (label.d_partitions[i].p_fstype) {
case 1: s = BALKAN_PART_SWAP; break;
case 8: s = BALKAN_PART_EXT2; break;
default: s = BALKAN_PART_OTHER; break;
}
table->parts[i].type = s;
}
}
return 0;
}
#ifdef STANDALONE_TEST
void main() {
int fd;
int i;
struct partitionTable table;
fd = open("/dev/hda", O_RDONLY);
printf("rc= %d\n", bsdlReadTable(fd, &table));
for (i = 0; i < table.maxNumPartitions; i++) {
if (table.parts[i].type == -1) continue;
printf("%d: %x %d\n", i, table.parts[i].type, table.parts[i].size);
}
}
#endif
|