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

📄 vnode_aff.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    if(next_datasize == vallen){		/* We can just write in place! */		int r = aff_write_seg(af,name,arg,value,vallen);		return r;	    }	    /* Invalidate this segment and continue scanning */	    	    uint64 loc_invalidated = next_segment_loc; // remember where this is	    aff_write_ignore(af,next_datasize+strlen(name));	    uint64 loc_before_seek = ftello(af->aseg); // before the seek	    fseeko(af->aseg,(uint64)0,SEEK_END);              // go to the end of the file	    uint64 pos_eof = ftello(af->aseg);	    if(pos_eof == loc_before_seek){		/* Apparently I didn't move at all with the seek.		 * If the segment being written is larger than the segment being replaced,		 * we can just backspace.		 */		if(next_segsize < vallen){		    //fprintf(stderr,"  *** seeking to %qd\n",loc_invalidated);		    fseeko(af->aseg,loc_invalidated,SEEK_SET);		}	    }	    break;			// and exit this loop	}	/* If this is an AF_IGNORE, see if it is a close match */	if(next_segment_name[0]==AF_IGNORE[0]){	    if(next_datasize>=size_needed && ((next_datasize<size_closest || size_closest==0))){		size_closest = next_datasize;		loc_closest  = next_segment_loc;	    }	}	fseeko(af->aseg,next_segsize,SEEK_CUR); // skip this segment    }    /* Ready to write */    //fprintf(stderr,"size_closest=%d\n",size_closest);    if(size_closest>0){	/* Yes. Put it here and put a new AF_IGNORE in the space left-over	 * TODO: If the following space is also an AF_IGNORE, then combine the two.	 */#ifdef DEBUG	fprintf(stderr,"size_closest=%d\n",size_closest);	fprintf(stderr,"loc_closest=%qd\n",loc_closest);	fprintf(stderr,"*** Squeezing it in at %qd. name=%s. vallen=%d\n",loc_closest,name,vallen);#endif		fseeko(af->aseg,loc_closest,SEEK_SET); // move to the location	aff_write_seg(af,name,arg,value,vallen); // write the new segment		int newsize = size_closest - vallen - aff_ignore_overhead() - strlen(name);		aff_write_ignore(af,newsize); // write the smaller ignore	return 0;    }    /* Just write to the end of the file */    return aff_write_seg(af,name,arg,value,vallen); // just write at the end}/* Delete the first occurance of the named segment. * Special case code: See if the segment being deleted * is the last segment. If it is, truncate the file... * This handles the case of AF_DIRECTORY and possibly other cases * as well... */static int aff_del_seg(AFFILE *af,const char *segname){    af_toc_del(af,segname);		// remove it from the directory    /* Find out if the last segment is the one we are deleting;     * If so, we can just truncate the file.     * Note: we can't do this on Windows because _chsize(),      * the equivillent of ftruncate(), takes a 32-bit argument.     */#ifndef WIN32    char last_segname[AF_MAX_NAME_LEN];    int64 last_pos;    af_last_seg(af,last_segname,sizeof(last_segname),&last_pos);    if(strcmp(segname,last_segname)==0){	fflush(af->aseg);		// flush any ouput	ftruncate(fileno(af->aseg),last_pos); // make the file shorter	return 0;    }#endif    size_t datasize=0,segsize=0;    if(aff_find_seg(af,segname,0,&datasize,&segsize)!=0){	return -1;			// nothing to delete?    }    /* Now wipe it out */    size_t ignore_size = datasize+strlen(segname);    aff_write_ignore(af,ignore_size);    return 0;}#ifdef HAVE_OPENSSL_RAND_H#include <openssl/rand.h>#endif/*  * af_make_badflag: * Create a randomized bag flag and * leave an empty segment of how many badsectors there are * in the image... */int af_make_badflag(AFFILE *af){#ifdef HAVE_OPENSSL_RAND_H    RAND_pseudo_bytes(af->badflag,af->image_sectorsize);    strcpy((char *)af->badflag,"BAD SECTOR");#else    for(int i=0;i<af->image_sectorsize;i++){      af->badflag[i] = rand() & 0xff;    }#endif    af->badflag_set = 1;    if(af_update_seg(af,AF_BADFLAG,0,af->badflag,af->image_sectorsize)){	return -1;    }    if(af_update_segq(af,AF_BADSECTORS,0)){	return -1;    }    return 0;}/* aff_create: * af is an empty file that is being set up. */static int aff_create(AFFILE *af){    fwrite(AF_HEADER,1,8,af->aseg);  // writes the header     af_toc_build(af);	             // build the toc (will be pretty small)    af_make_badflag(af);	     // writes the flag for bad blocks        char *version = xstr(PACKAGE_VERSION);    af_update_seg(af,AF_AFFLIB_VERSION,0,version,strlen(version));    #ifdef HAVE_GETPROGNAME    const char *progname = getprogname();    if(af_update_seg(af,AF_CREATOR,0,progname,strlen(progname))) return -1;#endif    if(af_update_seg(af,AF_AFF_FILE_TYPE,0,"AFF",3)) return -1;    return 0;}/**************************************************************** *** User-visible functions. ****************************************************************/static int aff_open(AFFILE *af){    int fd = open(af->fname,af->openflags | O_BINARY,af->openmode);    if(fd<0){				// couldn't open	return -1;    }    af->compression_type     = AF_COMPRESSION_ALG_ZLIB; // default    af->compression_level    = Z_DEFAULT_COMPRESSION;    /* Open the FILE  for the AFFILE */    char strflag[8];    strcpy(strflag,"rb");		// we have to be able to read    if(af->openflags & O_RDWR) 	strcpy(strflag,"w+b");     af->aseg = fdopen(fd,strflag);    if(!af->aseg){      (*af->error_reporter)("fdopen(%d,%s)",fd,strflag);      return -1;    }    /* Get file size */    struct stat sb;    if(fstat(fd,&sb)){	(*af->error_reporter)("aff_open: fstat(%s): ",af->fname);	// this should not happen	return -1;    }    /* If file is empty, then put out an AFF header, badflag, and AFF version */    if(sb.st_size==0){	return aff_create(af);    }        /* We are opening an existing file. Verify once more than it is an AFF file     * and skip past the header...     */    char buf[8];    if(fread(buf,sizeof(buf),1,af->aseg)!=1){	/* Hm. End of file. That shouldn't happen here. */	(*af->error_reporter)("aff_open: couldn't read AFF header on existing file?");	return -1;			// should not happen    }    if(strcmp(buf,AF_HEADER)!=0){	buf[7] = 0;	(*af->error_reporter)("aff_open: %s is not an AFF file (header=%s)\n",			      af->fname,buf);	return -1;    }    /* File has been validated */    if(af_toc_build(af)) return -1;	// build the TOC    return 0;				// everything must be okay.}static bool last4_is_aff(const char *filename){    if(strlen(filename)>4){	const char *last4 = filename+strlen(filename)-4;	if(strcasecmp(last4,".aff")==0) return 1;    }    return 0;}/* Return 1 if a file is an AFF file */static int aff_identify_file(const char *filename,int exists){    if(exists && access(filename,R_OK)!=0) return 0;	// needs to exist and it doesn't    int fd = open(filename,O_RDONLY | O_BINARY);    if(fd>0){	int len = strlen(AF_HEADER)+1;		char buf[64];	int r = read(fd,buf,len);	close(fd);	if(r==len){			// if I could read the header	    if(strcmp(buf,AF_HEADER)==0) return 1; // must be an AFF file	    return 0;			// not an AFF file	}	/* If it is a zero-length file and the file extension ends AFF,	 * then let it be an AFF file...	 */	if(r==0 && last4_is_aff(filename)) return 1;	return 0;			// must not be an aff file    }    /* File doesn't exist. Is this an AFF name? */    if(af_ext_is(filename,"aff")) return 1;    return 0;}/* * aff_close: * If the imagesize changed, write out a new value. */static int aff_close(AFFILE *af){    fclose(af->aseg);    return 0;}static int aff_vstat(AFFILE *af,struct af_vnode_info *vni){    memset(vni,0,sizeof(*vni));		// clear it    vni->imagesize = af->image_size;		// we can just return this    vni->pagesize = af->image_pagesize;    vni->supports_compression = 1;    vni->has_pages            = 1;    vni->supports_metadata    = 1;    return 0;}struct af_vnode vnode_aff = {    AF_IDENTIFY_AFF,    AF_VNODE_TYPE_PRIMITIVE|AF_VNODE_TYPE_RELIABLE,    "AFF",    aff_identify_file,    aff_open,    aff_close,    aff_vstat,    aff_get_seg,    aff_get_next_seg,    aff_rewind_seg,    aff_update_seg,    aff_del_seg,    0,				// read; keep 0    0				// write};

⌨️ 快捷键说明

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