2d6b5baa9faf40b9a6b369fd759ae08949651707
[project/mountd.git] / fs.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <error.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9
10 #include "include/fs.h"
11
12 typedef int (*dfunc)(int);
13
14 unsigned short
15 get_le_short(void *from)
16 {
17 unsigned char *p = from;
18 return ((unsigned short)(p[1]) << 8) +
19 (unsigned short)p[0];
20 }
21
22 unsigned int get_le_long(void *from)
23 {
24 unsigned char *p = from;
25 return ((unsigned int)(p[3]) << 24) +
26 ((unsigned int)(p[2]) << 16) +
27 ((unsigned int)(p[1]) << 8) +
28 (unsigned int)p[0];
29 }
30
31 unsigned short get_be_short(void *from)
32 {
33 unsigned char *p = from;
34 return ((unsigned short)(p[0]) << 8) +
35 (unsigned short)p[1];
36 }
37
38 unsigned int get_be_long(void *from)
39 {
40 unsigned char *p = from;
41 return ((unsigned int)(p[0]) << 24) +
42 ((unsigned int)(p[1]) << 16) +
43 ((unsigned int)(p[2]) << 8) +
44 (unsigned int)p[3];
45 }
46
47 int get_buffer(int fd, unsigned char *b, int offset, int len)
48 {
49 if(lseek(fd, offset, SEEK_SET) != offset)
50 return -1;
51 if(read(fd, b, len) != len)
52 return -1;
53 return 0;
54 }
55
56 #define MBR_BUF_SIZE 512
57 int detect_mbr(int fd)
58 {
59 int ret = NONE;
60 unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE);
61 if(get_buffer(fd, buffer, 0, MBR_BUF_SIZE) != 0)
62 goto out;
63 if((buffer[510] == 0x55) && (buffer[511] == 0xAA))
64 ret = MBR;
65 out:
66 free(buffer);
67 return ret;
68 }
69
70 #define EFI_BUF_OFFSET 512
71 #define EFI_BUF_SIZE 512
72 int detect_efi(int fd)
73 {
74 int ret = NONE;
75 unsigned char *buffer = (unsigned char*)malloc(EFI_BUF_SIZE);
76 if(get_buffer(fd, buffer, EFI_BUF_OFFSET, EFI_BUF_SIZE) != 0)
77 goto out;
78 if(!memcmp(buffer, "EFI PART", 8))
79 ret = EFI;
80 out:
81 free(buffer);
82 return ret;
83 }
84
85 #define EXT2_BUF_SIZE 1024
86 int detect_ext23(int fd)
87 {
88 int ret = NONE;
89 unsigned char *buffer = (unsigned char*)malloc(EXT2_BUF_SIZE);
90 if(get_buffer(fd, buffer, 1024, EXT2_BUF_SIZE) != 0)
91 goto out;
92 if(get_le_short(buffer + 56) == 0xEF53)
93 {
94 if((get_le_long(buffer + 96) & 0x0008)
95 || (get_le_long(buffer + 92) & 0x0004))
96 ret = EXT3;
97 else
98 ret = EXT2;
99 }
100 out:
101 free(buffer);
102 return ret;
103 }
104
105 #define FAT_BUF_SIZE 512
106 int detect_fat(int fd)
107 {
108 int ret = NONE;
109 unsigned char *buffer = (unsigned char*)malloc(FAT_BUF_SIZE);
110 if(get_buffer(fd, buffer, 0, FAT_BUF_SIZE) != 0)
111 goto out;
112
113 if (((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9))
114 && ((buffer[510] & 0xff) == 0x55) /*&& ((buffer[511] & 0xff == 0xAA))*/
115 && (memcmp(buffer + 3, "NTFS ", 8)))
116 ret = FAT;
117 out:
118 free(buffer);
119 return ret;
120 }
121
122 #define HFSPLUS_VOL_JOURNALED (1 << 13)
123 #define HFSPLUS_BUF_SIZE 512
124 int detect_hfsplus(int fd)
125 {
126 int ret = NONE;
127 unsigned short magic;
128 unsigned int journal;
129 unsigned char *buffer = (unsigned char*)malloc(HFSPLUS_BUF_SIZE);
130 if(get_buffer(fd, buffer, 1024, HFSPLUS_BUF_SIZE) != 0)
131 goto out;
132 magic = get_be_short(buffer);
133 journal = get_be_long(buffer + 4) & HFSPLUS_VOL_JOURNALED;
134 if(magic == 0x482B)
135 {
136 if(!journal)
137 ret = HFSPLUS;
138 // else
139 // ret = HFSPLUSJOURNAL;
140 }
141 out:
142 free(buffer);
143 return ret;
144 }
145
146 #define NTFS_BUF_SIZE 512
147 int detect_ntfs(int fd)
148 {
149 int ret = NONE;
150 unsigned char *buffer = (unsigned char*)malloc(NTFS_BUF_SIZE);
151 if(get_buffer(fd, buffer, 0, NTFS_BUF_SIZE) != 0)
152 goto out;
153 if(!memcmp(buffer + 3, "NTFS ", 8))
154 ret = NTFS;
155 out:
156 free(buffer);
157 return ret;
158 }
159
160 #define EXTENDED_BUF_SIZE 512
161 int detect_extended(int fd)
162 {
163 int ret = NONE;
164 unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE);
165 if(get_buffer(fd, buffer, 0, 512) != 0)
166 goto out;
167 if((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9))
168 goto out;
169 if(((buffer[510] & 0xff) == 0x55) && ((buffer[511] & 0xff) == 0xAA))
170 ret = EXTENDED;
171 out:
172 free(buffer);
173 return ret;
174 }
175
176 dfunc funcs[] = {
177 detect_ext23,
178 detect_fat,
179 detect_ntfs,
180 detect_hfsplus,
181 detect_extended,
182 detect_efi,
183 detect_mbr,
184 };
185
186 int detect_fs(char *device)
187 {
188 int i = 0;
189 int ret = NONE;
190 int fd;
191
192 fd = open(device, O_RDONLY);
193 if(!fd)
194 return NONE;
195
196 while((i < 6) && (ret == NONE))
197 ret = funcs[i++](fd);
198
199 close(fd);
200
201 return ret;
202 }