/* * detect.c * Detection dispatching * * Copyright (c) 2003 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "global.h" /* * external detection functions */ /* in amiga.c */ void detect_amiga_partmap(SECTION *section, int level); void detect_amiga_fs(SECTION *section, int level); /* in apple.c */ void detect_apple_partmap(SECTION *section, int level); void detect_apple_volume(SECTION *section, int level); void detect_udif(SECTION *section, int level); /* in atari.c */ void detect_atari_partmap(SECTION *section, int level); /* in dos.c */ void detect_dos_partmap(SECTION *section, int level); void detect_gpt_partmap(SECTION *section, int level); void detect_fat(SECTION *section, int level); void detect_ntfs(SECTION *section, int level); void detect_hpfs(SECTION *section, int level); void detect_dos_loader(SECTION *section, int level); /* in cdrom.c */ void detect_iso(SECTION *section, int level); void detect_cdrom_misc(SECTION *section, int level); /* in udf.c */ void detect_udf(SECTION *section, int level); /* in linux.c */ void detect_ext23(SECTION *section, int level); void detect_reiser(SECTION *section, int level); void detect_reiser4(SECTION *section, int level); void detect_linux_raid(SECTION *section, int level); void detect_linux_lvm(SECTION *section, int level); void detect_linux_lvm2(SECTION *section, int level); void detect_linux_swap(SECTION *section, int level); void detect_linux_misc(SECTION *section, int level); void detect_linux_loader(SECTION *section, int level); /* in unix.c */ void detect_jfs(SECTION *section, int level); void detect_xfs(SECTION *section, int level); void detect_ufs(SECTION *section, int level); void detect_sysv(SECTION *section, int level); void detect_bsd_disklabel(SECTION *section, int level); void detect_bsd_loader(SECTION *section, int level); void detect_solaris_disklabel(SECTION *section, int level); void detect_solaris_vtoc(SECTION *section, int level); void detect_qnx(SECTION *section, int level); void detect_vxfs(SECTION *section, int level); /* in beos.c */ void detect_bfs(SECTION *section, int level); void detect_beos_loader(SECTION *section, int level); /* in compressed.c */ void detect_compressed(SECTION *section, int level); /* in cdimage.c */ void detect_cdimage(SECTION *section, int level); /* in vpc.c */ void detect_vhd(SECTION *section, int level); /* in cloop.c */ void detect_cloop(SECTION *section, int level); /* in archives.c */ void detect_archive(SECTION *section, int level); /* in blank.c */ void detect_blank(SECTION *section, int level); /* * list of detectors */ DETECTOR detectors[] = { /* 1: disk image formats */ detect_vhd, /* may stop */ detect_cdimage, /* may stop */ detect_cloop, detect_udif, /* 2: boot code */ detect_linux_loader, detect_bsd_loader, detect_dos_loader, detect_beos_loader, /* 3: partition tables */ detect_bsd_disklabel, /* may stop, recurses with FLAG_IN_DISKLABEL */ detect_solaris_disklabel, /* may stop, recurses with FLAG_IN_DISKLABEL */ detect_solaris_vtoc, detect_amiga_partmap, detect_apple_partmap, detect_atari_partmap, detect_dos_partmap, detect_gpt_partmap, /* 4: file systems */ detect_amiga_fs, detect_apple_volume, detect_fat, detect_ntfs, detect_hpfs, detect_udf, detect_cdrom_misc, detect_iso, detect_ext23, detect_reiser, detect_reiser4, detect_linux_raid, detect_linux_lvm, detect_linux_lvm2, detect_linux_swap, detect_linux_misc, detect_jfs, detect_xfs, detect_ufs, detect_sysv, detect_qnx, detect_vxfs, detect_bfs, /* 5: file formats */ detect_archive, detect_compressed, /* this is here because of boot disks */ /* 6: blank formatted disk */ detect_blank, NULL }; /* * internal stuff */ static void detect(SECTION *section, int level); static int stop_flag = 0; /* * analyze a given source */ void analyze_source(SOURCE *s, int level) { SECTION section; /* Allow custom analyzing using special info available to the data source implementation. The analyze() function must either call through to analyze_source_special() or return zero. */ if (s->analyze != NULL) { if ((*s->analyze)(s, level)) return; } section.source = s; section.pos = 0; section.size = s->size_known ? s->size : 0; section.flags = 0; detect(§ion, level); } /* * analyze part of a given source */ void analyze_source_special(SOURCE *s, int level, u8 pos, u8 size) { SECTION section; section.source = s; section.pos = pos; section.size = size; section.flags = 0; detect(§ion, level); } /* * recursively analyze a portion of a SECTION */ void analyze_recursive(SECTION *section, int level, u8 rel_pos, u8 size, int flags) { SOURCE *s; SECTION rs; /* sanity */ if (rel_pos == 0 && (flags & FLAG_IN_DISKLABEL) == 0) return; s = section->source; if (s->size_known && (section->pos + rel_pos >= s->size)) return; rs.source = s; rs.pos = section->pos + rel_pos; rs.size = size; rs.flags = section->flags | flags; detect(&rs, level); } /* * detection dispatching */ static void detect(SECTION *section, int level) { int i; /* run the modularized detectors */ for (i = 0; detectors[i] && !stop_flag; i++) (*detectors[i])(section, level); stop_flag = 0; } /* * break the detection loop */ void stop_detect(void) { stop_flag = 1; } /* EOF */