2 * Based on libdisk from xfsprogs and Linux fdisk.
4 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
10 #include <sys/types.h>
11 #include <netinet/in.h>
16 /* we need to read two sectors, beacuse BSD label offset is 512 */
17 #define PTTYPE_BUFSIZ (2 * DEFAULT_SECTOR_SIZE) /* 1024 */
22 struct sgi_device_parameter { /* 48 bytes */
26 unsigned char sparecyl;
27 unsigned short pcylcount;
28 unsigned short head_vol0;
29 unsigned short ntrks; /* tracks in cyl 0 or vol 0 */
30 unsigned char cmd_tag_queue_depth;
31 unsigned char unused0;
32 unsigned short unused1;
33 unsigned short nsect; /* sectors/tracks in cyl 0 or vol 0 */
35 unsigned short ilfact;
36 unsigned int flags; /* controller flags */
37 unsigned int datarate;
38 unsigned int retries_on_error;
39 unsigned int ms_per_word;
40 unsigned short xylogics_gap1;
41 unsigned short xylogics_syncdelay;
42 unsigned short xylogics_readdelay;
43 unsigned short xylogics_gap2;
44 unsigned short xylogics_readgate;
45 unsigned short xylogics_writecont;
48 #define SGI_VOLHDR 0x00
49 /* 1 and 2 were used for drive types no longer supported by SGI */
51 /* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */
52 #define SGI_VOLUME 0x06
55 #define SGI_RLVOL 0x09
57 #define SGI_XFSLOG 0x0b
60 #define ENTIRE_DISK SGI_VOLUME
64 #define SECTOR_SLIP 0x01
65 #define SECTOR_FWD 0x02
66 #define TRACK_FWD 0x04
67 #define TRACK_MULTIVOL 0x08
68 #define IGNORE_ERRORS 0x10
70 #define CMDTAGQ_ENABLE 0x40
72 struct sgi_volume_header {
73 unsigned int magic; /* expect SGI_LABEL_MAGIC */
74 unsigned short boot_part; /* active boot partition */
75 unsigned short swap_part; /* active swap partition */
76 unsigned char boot_file[16]; /* name of the bootfile */
77 struct sgi_device_parameter devparam; /* 1 * 48 bytes */
78 struct volume_directory { /* 15 * 16 bytes */
79 unsigned char vol_file_name[8]; /* a character array */
80 unsigned int vol_file_start; /* number of logical block */
81 unsigned int vol_file_size; /* number of bytes */
83 struct sgi_partition { /* 16 * 12 bytes */
84 unsigned int num_sectors; /* number of blocks */
85 unsigned int start_sector; /* must be cylinder aligned */
89 unsigned int fillbytes;
92 #define SGI_LABEL_MAGIC 0x0be5a941
95 twos_complement_32bit_sum(u_int32_t *base, int size)
100 size = size / sizeof(u_int32_t);
101 for (i = 0; i < size; i++)
102 sum = sum - ntohl(base[i]);
107 sgi_parttable(unsigned char *base)
110 struct sgi_volume_header *vh = (struct sgi_volume_header *) base;
112 if (ntohl(vh->magic) != SGI_LABEL_MAGIC)
114 csum = twos_complement_32bit_sum((uint32_t *)vh,
115 sizeof(struct sgi_volume_header));
123 dos_parttable(unsigned char *base)
125 return (base[510] == 0x55 && base[511] == 0xaa);
132 unsigned int magic; /* expect AIX_LABEL_MAGIC */
136 #define AIX_LABEL_MAGIC 0xc9c2d4c1
137 #define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9
138 #define aixlabel(x) ((aix_partition *)x)
141 aix_parttable(unsigned char *base)
143 return (aixlabel(base)->magic == AIX_LABEL_MAGIC ||
144 aixlabel(base)->magic == AIX_LABEL_MAGIC_SWAPPED);
151 unsigned char info[128]; /* Informative text string */
152 unsigned char spare0[14];
154 unsigned char spare1;
156 unsigned char spare2;
159 unsigned char spare1[246]; /* Boot information etc. */
160 unsigned short rspeed; /* Disk rotational speed */
161 unsigned short pcylcount; /* Physical cylinder count */
162 unsigned short sparecyl; /* extra sects per cylinder */
163 unsigned char spare2[4]; /* More magic... */
164 unsigned short ilfact; /* Interleave factor */
165 unsigned short ncyl; /* Data cylinder count */
166 unsigned short nacyl; /* Alt. cylinder count */
167 unsigned short ntrks; /* Tracks per cylinder */
168 unsigned short nsect; /* Sectors per track */
169 unsigned char spare3[4]; /* Even more magic... */
170 struct sun_partition {
171 u_int32_t start_cylinder;
172 u_int32_t num_sectors;
174 unsigned short magic; /* Magic number */
175 unsigned short csum; /* Label xor'd checksum */
178 #define SUN_LABEL_MAGIC 0xDABE
179 #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA
180 #define sunlabel(x) ((sun_partition *)x)
183 sun_parttable(unsigned char *base)
188 if (sunlabel(base)->magic != SUN_LABEL_MAGIC &&
189 sunlabel(base)->magic != SUN_LABEL_MAGIC_SWAPPED)
191 ush = ((unsigned short *) (sunlabel(base) + 1)) - 1;
192 while (ush >= (unsigned short *)sunlabel(base))
201 unsigned short magic;
205 #define MAC_LABEL_MAGIC 0x4552
206 #define MAC_PARTITION_MAGIC 0x504d
207 #define MAC_OLD_PARTITION_MAGIC 0x5453
208 #define maclabel(x) ((mac_partition *)x)
211 mac_parttable(unsigned char *base)
213 return (ntohs(maclabel(base)->magic) == MAC_LABEL_MAGIC ||
214 ntohs(maclabel(base)->magic) == MAC_PARTITION_MAGIC ||
215 ntohs(maclabel(base)->magic) == MAC_OLD_PARTITION_MAGIC);
219 * BSD subpartitions listed in a disklabel, under a dos-like partition.
221 #define BSD_DISKMAGIC 0x82564557UL /* The disk magic number */
222 #define BSD_DISKMAGIC_SWAPED 0x57455682UL
223 struct bsd_disklabel {
224 uint32_t magic; /* the magic number */
229 bsd_parttable(unsigned char *base)
231 struct bsd_disklabel *l = (struct bsd_disklabel *)
232 (base + (DEFAULT_SECTOR_SIZE * 1));
234 return (l->magic == BSD_DISKMAGIC || l->magic == BSD_DISKMAGIC_SWAPED);
238 get_pt_type_fd(int fd)
241 unsigned char buf[PTTYPE_BUFSIZ];
243 if (read(fd, buf, PTTYPE_BUFSIZ) != PTTYPE_BUFSIZ)
246 if (sgi_parttable(buf))
248 else if (sun_parttable(buf))
250 else if (aix_parttable(buf))
252 else if (dos_parttable(buf))
254 else if (mac_parttable(buf))
256 else if (bsd_parttable(buf))
263 get_pt_type(const char *device)
268 fd = open(device, O_RDONLY);
271 type = get_pt_type_fd(fd);
278 main(int argc, char **argv)
283 fprintf(stderr, "usage: %s <device>\n", argv[0]);
287 type = get_pt_type(argv[1]);
289 printf("Partition type: %s\n", type);