📄 detect.c
字号:
/* * 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 "detect.h"#include "file.h"static int stop_flag = 0;/* * list of detectors */typedef int (*DETECTOR)(SECTION* section, DT_Info* info);DETECTOR detectors_dif[] = { /* 1: disk image formats */ // detect_vhd, /* may stop */ // detect_cdimage, /* may stop */ // detect_udif, NULL };DETECTOR detectors_bc[] = { /* 2: boot code */ detect_linux_loader, // detect_bsd_loader, NULL };DETECTOR detectors_pt[] = { /* 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, NULL };DETECTOR detectors_fs[] = { /* 4: file systems */ // detect_amiga_fs, // detect_apple_volume, detect_fat, detect_ntfs, detect_hpfs, // detect_udf, // detect_iso, detect_ext23, detect_reiser, detect_linux_raid, detect_linux_lvm, detect_linux_swap, detect_linux_misc, // detect_jfs, // detect_xfs, // detect_ufs, // detect_sysv, // detect_qnx, // detect_bfs, NULL };DETECTOR detectors_ff[] = { /* 5: file formats */ // detect_archive, // detect_compressed, /* this is here because of boot disks */ /* 6: blank formatted disk */ // detect_blank, NULL };DT_Info* DT_detect(char* filename, int flags) { SOURCE* s; DT_Info* newinfo = NULL; DBG("Detecting %s, flags: %i", filename, flags); s = dt_analyze_source(filename); if(s == NULL) return NULL; DBG("SOURCE: size %lld, known: %i", s->size, s->size_known); if(s->type == DT_FILE || s->type == DT_BLOCK || s->type == DT_CHAR) { newinfo = dt_detect_source(s, filename, flags); } /* dt_detect_source closes the source, s already freed */ return newinfo;}SOURCE* dt_analyze_source(char* filename) { struct stat sb; SOURCE* s; int f; DBG("Analyzing %s", filename); s = (SOURCE*) malloc(sizeof(SOURCE)); if(s == NULL) return NULL; memset(s, 0, sizeof(SOURCE)); if(stat(filename, &sb) < 0) { error("Can't stat %.300s", filename); free(s); return NULL; } if (S_ISREG(sb.st_mode)) { s->type = DT_FILE; s->size = sb.st_size; s->size_known = 1; s->open = open_file; s->close = close_file; s->read_bytes = read_file; return s; } else if (S_ISBLK(sb.st_mode)) { s->type = DT_BLOCK; s->open = open_file; s->close = close_file; s->read_bytes = read_file; s->analyze = analyze_file; } else if (S_ISCHR(sb.st_mode)) { s->type = DT_CHAR; s->open = open_file; s->close = close_file; s->read_bytes = read_file; s->analyze = analyze_file; } else if (S_ISDIR(sb.st_mode)) { s->type = DT_DIR; error("'%s' is a directory", filename); return s; } else if (S_ISFIFO(sb.st_mode)) { s->type = DT_FIFO; error("'%s' is a FIFO", filename); return s; }#ifdef S_ISSOCK else if (S_ISSOCK(sb.st_mode)) { s->type = DT_SOCKET; error("'%s' is a socket", filename); return s; }#endif else { s->type = DT_SPECIAL; error("'%s' is an unknown kind of special file", filename); return s; } /* open for reading */ f = open(filename, O_RDONLY); if(f < 0) { errore("Can't open %.300s for reading (analyze)", filename); return s; } /* (try to) guard against TTY character devices */ if(s->type == DT_CHAR) { if(isatty(f)) { errore("%.300s: Is a TTY device", filename); free(s); return NULL; } } /* Now determine the size */ dt_getfilesize(f, s); close(f); return s;}DT_Info* dt_detect_source(SOURCE* s, char* filename, int flags) { SECTION section; DT_Info* newinfo = NULL; DBG("detect_source"); /* 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. */ /* DEPRECATED. currently only used for cdaccess.c */ if (s->analyze != NULL) { if ((*s->analyze)(s, newinfo)) return NULL; } section.source = s; section.pos = 0; section.size = s->size_known ? s->size : 0; section.flags = 0; section.detectorflags = flags; if(s->open != NULL && s->close != NULL) { /* open the source */ (*s->open)(s, filename); newinfo = dt_detect(§ion); /* close the source */ close_source(s); } else { error("Internal malfunction! Cannot open SOURCE: no open/close callbacks defined!"); } return newinfo;}/* returns DT_YES if filesystem detected, DT_NO if no filesystem could be detected, DT_ERROR if an error has occurred */DT_Info* dt_detect(SECTION* section) { int i; DT_Info* newinfo; if(section == NULL) return NULL; /* test sanity of section */ if(section->pos >= section->size) { DBG("No need to scan section!"); DBG("section: pos: %lld, size %lld", section->pos, section->size); return NULL; } newinfo = new_DT_Info(); if(newinfo == NULL) return NULL; /* run the modularized detectors */ DBG("run the modularized detectors"); stop_flag = 0; if(section->detectorflags & DFLAG_DIF) { newinfo->type = DT_OTHER; for (i = 0; detectors_dif[i] && !stop_flag; i++) { DBG("Detecting Disk Image Formats (%i)", i); if( (*detectors_dif[i])(section, newinfo) == DT_YES) { return newinfo; } } } if(section->detectorflags & DFLAG_BC) { newinfo->type = DT_BOOTCODE; for (i = 0; detectors_bc[i] && !stop_flag; i++) { DBG("Detecting Bootcode (%i)", i); if( (*detectors_bc[i])(section, newinfo) == DT_YES) { return newinfo; } } } if(section->detectorflags & DFLAG_PT) { newinfo->type = DT_PARTMAP; for (i = 0; detectors_pt[i] && !stop_flag; i++) { DBG("Detecting Partition Maps (%i)", i); if( (*detectors_pt[i])(section, newinfo) == DT_YES) { return newinfo; } } } if(section->detectorflags & DFLAG_FS) { newinfo->type = DT_FS; for (i = 0; detectors_fs[i] && !stop_flag; i++) { DBG("Detecting Filesystems (%i)", i); if( (*detectors_fs[i])(section, newinfo) == DT_YES) { return newinfo; } } } if(section->detectorflags & DFLAG_FF) { newinfo->type = DT_OTHER; for (i = 0; detectors_ff[i] && !stop_flag; i++) { DBG("Detecting File Formats (%i)", i); if( (*detectors_ff[i])(section, newinfo) == DT_YES) { return newinfo; } } } return NULL;}/* break the detection loop */void stop_detect(void) { stop_flag = 1;}DT_Info* new_DT_Info() { DT_Info* newinfo = (DT_Info*) malloc(sizeof(DT_Info)); if(newinfo == NULL) { error("Not enough memory to create new DT_Info"); return NULL; } memset(newinfo, 0, sizeof(DT_Info)); return newinfo;}void remove_DT_Info(DT_Info* info) { if(info == NULL) return; while(info) { info = remove_single_DT_Info(info); }}#define DT_REMOVE(value) if(value != NULL) free(value)DT_Info* remove_single_DT_Info(DT_Info* info) { DT_Info* tmp; if(info == NULL) return NULL; DT_REMOVE(info->bootcode.loader); DT_REMOVE(info->bootcode.loader_version_string); DT_REMOVE(info->bootcode.data); DT_REMOVE(info->fs.type_version_name); DT_REMOVE(info->fs.type_name); DT_REMOVE(info->fs.volume_name); DT_REMOVE(info->partmap.part_type_name); /* dt_other unused right now */ tmp = info->next; free(info); return tmp;}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -