summaryrefslogtreecommitdiffstats
path: root/fdisk/partitiontype.c
blob: 0ee44a0bab32a640140e5e5bce3048bed93c3aa6 (plain) (blame)
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
/*
 * partitiontype.c, aeb, 2001-09-10
 *
 * call: partitiontype device
 *
 * either exit(1), or exit(0) with a single line of output
 * DOS: sector 0 has a DOS signature.
 */
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

struct aix_label {
	unsigned int   magic;
	/* more ... */
};

#define	AIX_LABEL_MAGIC		0xc9c2d4c1
#define	AIX_LABEL_MAGIC_SWAPPED	0xc1d4c2c9

struct bsd_label {
	unsigned int   magic;
	unsigned char  stuff[128];
	unsigned int   magic2;
	/* more ... */
};

#define BSD_LABEL_MAGIC         0x82564557

struct sgi_label {
	unsigned int   magic;
	/* more ... */
};

#define	SGI_LABEL_MAGIC		0x0be5a941
#define	SGI_LABEL_MAGIC_SWAPPED	0x41a9e50b

struct sun_label {
	unsigned char stuff[508];
	unsigned short magic;      /* Magic number */
	unsigned short csum;       /* Label xor'd checksum */
};

#define SUN_LABEL_MAGIC          0xDABE
#define SUN_LABEL_MAGIC_SWAPPED  0xBEDA

int
main(int argc, char **argv) {
	int fd, n;
	unsigned char buf[1024];
	struct aix_label *paix;
	struct bsd_label *pbsd;
	struct sgi_label *psgi;
	struct sun_label *psun;

	if (argc != 2) {
		fprintf(stderr, "call: %s device\n", argv[0]);
		exit(1);
	}
	fd = open(argv[1], O_RDONLY);
	if (fd == -1) {
		perror(argv[1]);
		fprintf(stderr, "%s: cannot open device %s\n",
			argv[0], argv[1]);
		exit(1);
	}
	n = read(fd, buf, sizeof(buf));
	if (n != sizeof(buf)) {
		if (n == -1)
			perror(argv[1]);
		fprintf(stderr, "%s: cannot read device %s\n",
			argv[0], argv[1]);
		exit(1);
	}

	psun = (struct sun_label *)(&buf);
	if (psun->magic == SUN_LABEL_MAGIC ||
	    psun->magic == SUN_LABEL_MAGIC_SWAPPED) {
		unsigned short csum = 0, *p;
		int i;

		for (p = (unsigned short *)(&buf);
		     p < (unsigned short *)(&buf[512]); p++)
			csum ^= *p;

		if (csum == 0) {
			printf("SUN\n");
			exit(0);
		}
	}

	pbsd = (struct bsd_label *)(&buf[512]);
	if (pbsd->magic == BSD_LABEL_MAGIC &&
	    pbsd->magic2 == BSD_LABEL_MAGIC) {
		printf("BSD\n");
		exit(0);
	}

	pbsd = (struct bsd_label *)(&buf[64]);
	if (pbsd->magic == BSD_LABEL_MAGIC &&
	    pbsd->magic2 == BSD_LABEL_MAGIC) {
		printf("BSD\n");
		exit(0);
	}

	paix = (struct aix_label *)(&buf);
	if (paix->magic == AIX_LABEL_MAGIC ||
	    paix->magic == AIX_LABEL_MAGIC_SWAPPED) {
		printf("AIX\n");
		exit(0);
	}

	psgi = (struct sgi_label *)(&buf);
	if (psgi->magic == SGI_LABEL_MAGIC ||
	    psgi->magic == SGI_LABEL_MAGIC_SWAPPED) {
		printf("SGI\n");
		exit(0);
	}

	if (buf[510] == 0x55 && buf[511] == 0xaa) {
		printf("DOS\n");
		exit(0);
	}
#if 0
	fprintf(stderr, "%s: do not recognize any label on %s\n",
		argv[0], argv[1]);
#endif
	exit(1);		/* unknown */
}