1 /*
2 * detect.c
3 * Detection dispatching
4 *
5 * Copyright (c) 2003 Christoph Pfisterer
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy,
11 * modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28 #include "global.h"
29
30 /*
31 * external detection functions
32 */
33
34 /* in amiga.c */
35 void detect_amiga_partmap(SECTION *section, int level);
36 void detect_amiga_fs(SECTION *section, int level);
37
38 /* in apple.c */
39 void detect_apple_partmap(SECTION *section, int level);
40 void detect_apple_volume(SECTION *section, int level);
41 void detect_udif(SECTION *section, int level);
42
43 /* in atari.c */
44 void detect_atari_partmap(SECTION *section, int level);
45
46 /* in dos.c */
47 void detect_dos_partmap(SECTION *section, int level);
48 void detect_gpt_partmap(SECTION *section, int level);
49 void detect_fat(SECTION *section, int level);
50 void detect_ntfs(SECTION *section, int level);
51 void detect_hpfs(SECTION *section, int level);
52 void detect_dos_loader(SECTION *section, int level);
53
54 /* in cdrom.c */
55 void detect_iso(SECTION *section, int level);
56 void detect_cdrom_misc(SECTION *section, int level);
57
58 /* in udf.c */
59 void detect_udf(SECTION *section, int level);
60
61 /* in linux.c */
62 void detect_ext23(SECTION *section, int level);
63 void detect_reiser(SECTION *section, int level);
64 void detect_reiser4(SECTION *section, int level);
65 void detect_linux_raid(SECTION *section, int level);
66 void detect_linux_lvm(SECTION *section, int level);
67 void detect_linux_lvm2(SECTION *section, int level);
68 void detect_linux_swap(SECTION *section, int level);
69 void detect_linux_misc(SECTION *section, int level);
70 void detect_linux_loader(SECTION *section, int level);
71
72 /* in unix.c */
73 void detect_jfs(SECTION *section, int level);
74 void detect_xfs(SECTION *section, int level);
75 void detect_ufs(SECTION *section, int level);
76 void detect_sysv(SECTION *section, int level);
77 void detect_bsd_disklabel(SECTION *section, int level);
78 void detect_bsd_loader(SECTION *section, int level);
79 void detect_solaris_disklabel(SECTION *section, int level);
80 void detect_solaris_vtoc(SECTION *section, int level);
81 void detect_qnx(SECTION *section, int level);
82 void detect_vxfs(SECTION *section, int level);
83
84 /* in beos.c */
85 void detect_bfs(SECTION *section, int level);
86 void detect_beos_loader(SECTION *section, int level);
87
88 /* in compressed.c */
89 void detect_compressed(SECTION *section, int level);
90
91 /* in cdimage.c */
92 void detect_cdimage(SECTION *section, int level);
93
94 /* in vpc.c */
95 void detect_vhd(SECTION *section, int level);
96
97 /* in cloop.c */
98 void detect_cloop(SECTION *section, int level);
99
100 /* in archives.c */
101 void detect_archive(SECTION *section, int level);
102
103 /* in blank.c */
104 void detect_blank(SECTION *section, int level);
105
106 /*
107 * list of detectors
108 */
109
110 DETECTOR detectors[] = {
111 /* 1: disk image formats */
112 detect_vhd, /* may stop */
113 detect_cdimage, /* may stop */
114 detect_cloop,
115 detect_udif,
116 /* 2: boot code */
117 detect_linux_loader,
118 detect_bsd_loader,
119 detect_dos_loader,
120 detect_beos_loader,
121 /* 3: partition tables */
122 detect_bsd_disklabel, /* may stop, recurses with FLAG_IN_DISKLABEL */
123 detect_solaris_disklabel, /* may stop, recurses with FLAG_IN_DISKLABEL */
124 detect_solaris_vtoc,
125 detect_amiga_partmap,
126 detect_apple_partmap,
127 detect_atari_partmap,
128 detect_dos_partmap,
129 detect_gpt_partmap,
130 /* 4: file systems */
131 detect_amiga_fs,
132 detect_apple_volume,
133 detect_fat,
134 detect_ntfs,
135 detect_hpfs,
136 detect_udf,
137 detect_cdrom_misc,
138 detect_iso,
139 detect_ext23,
140 detect_reiser,
141 detect_reiser4,
142 detect_linux_raid,
143 detect_linux_lvm,
144 detect_linux_lvm2,
145 detect_linux_swap,
146 detect_linux_misc,
147 detect_jfs,
148 detect_xfs,
149 detect_ufs,
150 detect_sysv,
151 detect_qnx,
152 detect_vxfs,
153 detect_bfs,
154 /* 5: file formats */
155 detect_archive,
156 detect_compressed, /* this is here because of boot disks */
157 /* 6: blank formatted disk */
158 detect_blank,
159
160 NULL };
161
162
163 /*
164 * internal stuff
165 */
166
167 static void detect(SECTION *section, int level);
168
169 static int stop_flag = 0;
170
171 /*
172 * analyze a given source
173 */
174
analyze_source(SOURCE * s,int level)175 void analyze_source(SOURCE *s, int level)
176 {
177 SECTION section;
178
179 /* Allow custom analyzing using special info available to the
180 data source implementation. The analyze() function must either
181 call through to analyze_source_special() or return zero. */
182 if (s->analyze != NULL) {
183 if ((*s->analyze)(s, level))
184 return;
185 }
186
187 section.source = s;
188 section.pos = 0;
189 section.size = s->size_known ? s->size : 0;
190 section.flags = 0;
191
192 detect(§ion, level);
193 }
194
195 /*
196 * analyze part of a given source
197 */
198
analyze_source_special(SOURCE * s,int level,u8 pos,u8 size)199 void analyze_source_special(SOURCE *s, int level, u8 pos, u8 size)
200 {
201 SECTION section;
202
203 section.source = s;
204 section.pos = pos;
205 section.size = size;
206 section.flags = 0;
207
208 detect(§ion, level);
209 }
210
211 /*
212 * recursively analyze a portion of a SECTION
213 */
214
analyze_recursive(SECTION * section,int level,u8 rel_pos,u8 size,int flags)215 void analyze_recursive(SECTION *section, int level,
216 u8 rel_pos, u8 size, int flags)
217 {
218 SOURCE *s;
219 SECTION rs;
220
221 /* sanity */
222 if (rel_pos == 0 && (flags & FLAG_IN_DISKLABEL) == 0)
223 return;
224 s = section->source;
225 if (s->size_known && (section->pos + rel_pos >= s->size))
226 return;
227
228 rs.source = s;
229 rs.pos = section->pos + rel_pos;
230 rs.size = size;
231 rs.flags = section->flags | flags;
232
233 detect(&rs, level);
234 }
235
236 /*
237 * detection dispatching
238 */
239
detect(SECTION * section,int level)240 static void detect(SECTION *section, int level)
241 {
242 int i;
243
244 /* run the modularized detectors */
245 for (i = 0; detectors[i] && !stop_flag; i++)
246 (*detectors[i])(section, level);
247 stop_flag = 0;
248 }
249
250 /*
251 * break the detection loop
252 */
253
stop_detect(void)254 void stop_detect(void)
255 {
256 stop_flag = 1;
257 }
258
259 /* EOF */
260