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(&section, 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(&section, 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