⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 afflib.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
字号:
/* * Copyright (c) 2005 *	Simson L. Garfinkel and Basis Technology, Inc.  *      All rights reserved. * * This code is derrived from software contributed by * Simson L. Garfinkel * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *    This product includes software developed by Simson L. Garfinkel *    and Basis Technology Corp. * 4. Neither the name of Simson Garfinkel, Basis Technology, or other *    contributors to this program may be used to endorse or promote *    products derived from this software without specific prior written *    permission. * * THIS SOFTWARE IS PROVIDED BY SIMSON GARFINKEL, BASIS TECHNOLOGY, * AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL SIMSON GARFINKEL, BAIS TECHNOLOGy, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE.   */#include "config.h"#include "afflib.h"#include "afflib_i.h"#include "vnode_raw.h"#include "vnode_split_raw.h"#include "vnode_afm.h"#include "vnode_aff.h"#include "vnode_afd.h"#include "vnode_ewf.h"#ifdef USE_S3#include "vnode_s3.h"#endif#include <fcntl.h>#include <assert.h>//#include <openssl/rand.h>#include <errno.h>// vnode implementations.// order mattersstruct af_vnode *af_vnode_array[] = {#ifdef USE_S3    &vnode_s3,				// must be first for s3:// interpertation#endif    &vnode_afd,     &vnode_afm,				// must be before aff    &vnode_aff,#ifdef USE_LIBEWF    &vnode_ewf,				// libewf#endif    &vnode_split_raw,			// must be before raw    &vnode_raw,				// greedy; must be last    0};/* Returns the name and offset of the last segment */int	af_last_seg(AFFILE *af,char *last_segname,int last_segname_len,int64 *pos){    /* Find the name of the last segment */    fseeko(af->aseg,0,SEEK_END);    af_backspace(af);			// back up one segment    *pos = ftello(af->aseg);	// remember where it is    last_segname[0] = 0;    return af_probe_next_seg(af,last_segname,last_segname_len,0,0,0,0);}/**************************************************************** *** GET FUNCTIONS ****************************************************************//**************************************************************** *** Probe the next segment: *** Return its name and argument, but don't advance the pointer.... *** Returns 0 on success, -1 on end of file or other error. ****************************************************************//**************************************************************** *** AFF creation functions ****************************************************************/static int aff_initialized = 0;int af_cache_debug = 0;FILE *af_trace = 0;void af_initialize(){    if(aff_initialized) return;    /* make sure things were compiled properly */    assert(sizeof(struct af_head)==8);    assert(sizeof(struct af_segment_head)==16);    assert(sizeof(struct af_segment_tail)==8);    const char *val = getenv(AFFLIB_CACHE_DEBUG);    if(val) af_cache_debug = atoi(val);    val = getenv(AFFLIB_TRACE);    if(val){	af_trace = fopen(val,"wa");	fprintf(af_trace,"============================\n");	fprintf(af_trace,"AFFLIB trace started\n");	setvbuf(af_trace,0,_IONBF,0);    }    aff_initialized = 1;    }/* Return 1 if a file is probably an AFF file * 0 if it is not. * -1 if failure. */int af_identify_file_type(const char *filename,int exists){    for(int i = 0; af_vnode_array[i]; i++){	if( (*af_vnode_array[i]->identify)(filename,exists)==1 ){	    return (af_vnode_array[i]->type);	}    }    return exists ? AF_IDENTIFY_NOEXIST : AF_IDENTIFY_ERR;}const char *af_identify_file_name(const char *filename,int exists){    for(int i = 0; af_vnode_array[i]; i++){	if( (*af_vnode_array[i]->identify)(filename,exists)==1 ){	    return (af_vnode_array[i]->name);	}    }    return 0;}AFFILE *af_open_with(const char *filename,int flags,int mode, struct af_vnode *v){    /* Alloate the space for the AFFILE structure */    AFFILE *af = (AFFILE *)calloc(sizeof(AFFILE),1);    af->v	  = v;    af->version   = 2;    af->openflags = flags | O_BINARY;	// make sure that we ask for binray    af->fname	  = strdup(filename);	                // remember file name    af->exists    = (access(filename,R_OK) == 0);	// does the file exist?    af->openmode  = mode;    af->image_sectorsize = 512;		// default size    af->error_reporter = warnx;    af->badflag   = (unsigned char *)malloc(af->image_sectorsize);    /* Right now just set up the cache by hand */    const char *cache_pages = getenv(AFFLIB_CACHE_PAGES);    if(cache_pages) af->num_pbufs = atoi(cache_pages);    if(af->num_pbufs<1) af->num_pbufs = AFFLIB_CACHE_PAGES_DEFAULT; // default valuen    af->pbcache   = (struct aff_pagebuf *)calloc(af->num_pbufs,sizeof(struct aff_pagebuf));    /* Try opening it! */    if((*af->v->open)(af)){			/* Got an error; Free what was allocated and return */	if(af->badflag) free(af->badflag);	if(af->pbcache) free(af->pbcache);	if(af->fname) free(af->fname);	memset(af,0,sizeof(*af));	// clean object reuse.	free(af);	return 0;    }    af_read_sizes(af);			// set up the metadata    if(af_trace) fprintf(af_trace,"af_open_with(%s,%o,%o,%s)\n",filename,flags,mode,v->name);    return af;}AFFILE *af_open(const char *filename,int flags,int mode){    if(!aff_initialized) af_initialize();        if(flags & O_WRONLY){	errno = EINVAL;	return 0;			// this flag not supported    }    int exists = (flags & O_CREAT) ? 0 : 1; // file most exist if O_CREAT not specified    /* Figure out it's format, then hand off to the correct subsystem. */    for(int i = 0; af_vnode_array[i]; i++){	/* Check to see if the implementation identifies the file */	if( (*af_vnode_array[i]->identify)(filename,exists)==1 ){	    return af_open_with(filename,flags,mode,af_vnode_array[i]);	}    }    return 0;				// can't figure it out.}/* Open a regular file as an affile. * Can only be a raw file... */AFFILE *af_freopen(FILE *file){    if(!aff_initialized) af_initialize();    AFFILE *af = (AFFILE *)calloc(sizeof(AFFILE),1);    af->v = &vnode_raw;    af->image_sectorsize = 512;		// default    raw_freopen(af,file);    return af;}#ifdef UNIX/* Open a regular file as an affile */AFFILE *af_popen(const char *command,const char *type){    if(!aff_initialized) af_initialize();    AFFILE *af = (AFFILE *)calloc(sizeof(AFFILE),1);    af->v   = &vnode_raw;    raw_popen(af,command,type);    af->image_sectorsize = 512;		// default    af->openflags = O_RDONLY;    af->fname     = strdup(command);    return af;}#endif/* Close the image */int af_close(AFFILE *af){    int ret = 0;    af_cache_flush(af);			// flush the cache (if writing)    if(af->writing && af->image_size != af->image_size_in_file){	af_update_segq(af,AF_IMAGESIZE,(int64)af->image_size);	af->image_size_in_file = af->image_size;    }    if(getenv(AFFLIB_CACHE_STATS)){	fputc('\n',stderr);	af_stats(af,stderr);    }    (*af->v->close)(af);    /* Clear out the cache */    if(af->pbcache){	for(int i=0;i<af->num_pbufs;i++){	    struct aff_pagebuf *p = &af->pbcache[i];	    if(p->pagebuf){		memset(p->pagebuf,0,af->image_pagesize); // clean object reuse		free(p->pagebuf);	    }	}	free(af->pbcache);    }    if(af->fname)	free(af->fname);    if(af->badflag)	free(af->badflag);    if(af->toc)         free(af->toc);    memset(af,0,sizeof(*af));		// clean object reuse    free(af);    return ret;}/* Seek in the virtual file */uint64 af_seek(AFFILE *af,int64 pos,int whence){    if(af_trace) fprintf(af_trace,"af_seek(%p,%"I64d",%d)\n",af,pos,whence);    uint64 new_pos=0;    switch(whence){    case SEEK_SET:	new_pos = pos;	break;    case SEEK_CUR:	new_pos += pos;	break;    case SEEK_END:	new_pos = af_get_imagesize(af) - pos;	break;    }    if(new_pos < 0) new_pos = 0;	   // new change    if(af->pos == new_pos) return af->pos; // no change    af->pos = new_pos;			// set the new position    return af->pos;}uint64  af_tell(AFFILE *af){    return af->pos;}/* Return if we are at the end of the file */int af_eof(AFFILE *af){    af_vnode_info vni;    if(af_vstat(af,&vni)) return -1;	// this is bad; we need vstat...    if(vni.use_eof) return vni.at_eof;	// if implementation wants to use it, use it    if(af->pos<0){			// pos shouldn't be <0	errno = EINVAL;	return -1;		// this is bad    }    return (int64)af->pos >= vni.imagesize;}void af_enable_writing(AFFILE *af,int flag){    af->writing = flag;}void af_set_callback(AFFILE *af,void (*wcb)(struct affcallback_info *)){    af->w_callback	  = wcb;}void af_enable_compression(AFFILE *af,int type,int level){    af->compression_type  = type;     af->compression_level = level;}int	af_compression_type(AFFILE *af){    return af->compression_type;}/* Return the 'extension' of str. * af_str("filename.aff") = ".aff" */const char *af_ext(const char *str){    int len = strlen(str);    if(len==0) return str;		// no extension    for(int i=len-1;i>0;i--){	if(str[i]=='.') return &str[i+1];    }    return str;}int af_ext_is(const char *filename,const char *ext){    return strcasecmp(af_ext(filename),ext)==0;}const char *af_filename(AFFILE *af){    return af->fname;}int	af_identify(AFFILE *af){    return af->v->type;}/* af_get_imagesize: * Return the byte # of last mapped byte in image, or size of device; */int64       af_get_imagesize(AFFILE *af){    struct af_vnode_info vni;    if(af_vstat(af,&vni)==0){	return vni.imagesize;    }    return -1;}int af_get_seg(AFFILE *af,const char *name,unsigned long *arg,unsigned char *data,size_t *datalen){    if(af->v->get_seg==0){	errno = ENOTSUP;	return -1;	// not supported by this file system    }    return (*af->v->get_seg)(af,name,arg,data,datalen);}int af_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg,			unsigned char *data,size_t *datalen_){    if(af->v->get_next_seg==0){	errno = ENOTSUP;	return -1;    }    return (*af->v->get_next_seg)(af,segname,segname_len,arg,data,datalen_);}int af_rewind_seg(AFFILE *af){    if(af->v->rewind_seg==0){	errno = ENOTSUP;	return -1;    }    return (*af->v->rewind_seg)(af);}int af_update_seg(AFFILE *af, const char *name,		  unsigned long arg,const void *value,unsigned int vallen){    if(af->v->update_seg==0){	errno = ENOTSUP;	return -1;	// not supported by this file system    }    int r = (*af->v->update_seg)(af,name,arg,value,vallen);    if(r==0) af->bytes_written += vallen;    return r;}int af_del_seg(AFFILE *af,const char *name){    if(af->v->del_seg==0){	errno = ENOTSUP;	return -1;	// not supported    }    return (*af->v->del_seg)(af,name);}int af_vstat(AFFILE *af,struct af_vnode_info *vni){    memset(vni,0,sizeof(*vni));		// clear it    if(af->v->vstat==0){	errno = ENOTSUP;	return -1;	// not supported    }    return (*af->v->vstat)(af,vni);}int af_has_pages(AFFILE *af){    struct af_vnode_info vni;    if(af_vstat(af,&vni)) return -1;	// can't figure it out    return vni.has_pages;		// will return 0 or 1}void af_stats(AFFILE *af,FILE *f){    fprintf(f,"AFSTATS for %s\n",af_filename(af));    fprintf(f,"Pages read: %"I64u"\n",af->pages_read);    fprintf(f,"Pages written: %"I64u"\n",af->pages_written);    fprintf(f,"Pages compressed: %"I64u"\n",af->pages_compressed);    fprintf(f,"Pages decompressed: %"I64u"\n",af->pages_decompressed);    fprintf(f,"Cache hits: %"I64u"\n",af->cache_hits);    fprintf(f,"Cache misses: %"I64u"\n",af->cache_misses);    fprintf(f,"Bytes copied: %"I64u"\n",af->bytes_memcpy);    }#ifndef HAVE_ERR#include <stdarg.h>void err(int eval,const char *fmt,...){  va_list ap;  va_start(ap,fmt);  vfprintf(stderr,fmt,ap);  fprintf(stderr,": %s\n",strerror(errno));  va_end(ap);  exit(eval);}#endif#ifndef HAVE_ERRX#include <stdarg.h>void errx(int eval,const char *fmt,...){  va_list ap;  va_start(ap,fmt);  vfprintf(stderr,fmt,ap);  fprintf(stderr,"%s\n",strerror(errno));  va_end(ap);  exit(eval);}#endif#ifndef HAVE_WARN#include <stdarg.h>void	warn(const char *fmt, ...){    va_list args;    va_start(args,fmt);    vfprintf(stderr,fmt, args);    fprintf(stderr,": %s",strerror(errno));}#endif#ifndef HAVE_WARNX#include <stdarg.h>void warnx(const char *fmt,...){  va_list ap;  va_start(ap,fmt);  vfprintf(stderr,fmt,ap);  va_end(ap);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -