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

📄 vnode_split_raw.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * AFFLIB(tm) * * Copyright (c) 2005, 2006 *	Simson L. Garfinkel and Basis Technology Corp. *      All rights reserved. * * This code is derrived from software contributed by Simson L. Garfinkel * * Support for split raw files and .afm files written by Joel N. Weber II * * 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 L. 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 L. 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 L. GARFINKEL, BASIS 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.   * * AFF and AFFLIB is a trademark of Simson Garfinkel and Basis Technology Corp. */#include "config.h"#include "afflib.h"#include "afflib_i.h"#include "vnode_split_raw.h"#ifdef HAVE_CTYPE_H#include <ctype.h>#endif#ifndef HAVE_ISDIGITstatic int isdigit(char ch){    return ch>='0' && ch<='9';}#endif/* split raw file implementation with optional metadata support */struct split_raw_private {    uint   num_raw_files;	// number of raw files    int    *fds;		// array of file descriptors for each open raw file    uint64 *pos;		// where we are in each file    char *first_raw_fname;    /* The filename of the first raw file. */    char *next_raw_fname;     /* The filename of the next raw file, or 0				 when one big file is used. */    int64 cur_page; // current page number, used for split_raw_get_next_seg};static inline struct split_raw_private *SPLIT_RAW_PRIVATE(AFFILE *af){    assert(af->v == &vnode_split_raw);    return (struct split_raw_private *)(af->vnodeprivate);}static inline const char *last4(const char *filename){  if(strlen(filename)>4) {    const char *l = filename+strlen(filename)-4;    return l;  }  return "";}/* Return 1 if a file is a split raw file... */static int split_raw_identify_file(const char *filename,int exists){    if(exists && access(filename,R_OK)!=0) return 0;	// needs to exist and it doesn't    const char *l4 = last4 (filename);    return (!strcmp (l4, ".000"))	|| (!strcmp (l4, ".001"))	|| (!strcasecmp (l4, ".aaa"));}/* split_raw_close: * Close each of the split files. */static int split_raw_close(AFFILE *af){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    for (uint64 i = 0; i < srp->num_raw_files; i++){	close (srp->fds[i]);    }    if (srp->fds)    free (srp->fds);    if (srp->pos)    free (srp->pos);    if (srp->first_raw_fname) free (srp->first_raw_fname);    if (srp->next_raw_fname) free (srp->next_raw_fname);    free(srp);    af->vnodeprivate = 0;    return 0;}/* increment_fname(): * takes filesname.000 and turns it into filename.001 * takes filename.aaa and makes it filename.aab * fn must be at least 3 characters long. * Returns 0 if successful, or -1  if it runs out of namespace. */static int increment_fname (char *fn){    /* Scan to the end of the string, minus 3 */    while (fn[3]) fn++;    if (fn[2] == '9') {	fn[2] = '0';	if (fn[1] == '9') {	    fn[1] = '0';	    if (fn[0] == '9')		return -1;	    fn[0]++;	} else {	    fn[1]++;	}    } else if (isdigit (fn[2])) {	fn[2]++;    } else if ((fn[2] == 'Z') || (fn[2] == 'z')) {	fn[2] -= 25;	fn[1]++;    } else if ((fn[2] == 'L') || (fn[2] == 'l')) {	/* We don't want to treat .afm as a valid raw file, since it is an	 * AFF metadata file.  So if we would end up with .afm as the name of the	 * raw file, report being out of namespace instead.	 */	if ((fn[1] == 'F') || (fn[1] == 'f'))	    errno = EINVAL;	    return -1;	fn[2]++;    } else {	fn[2]++;    }    return 0;}void srp_validate(AFFILE *af){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    for(unsigned int i=0;i<srp->num_raw_files;i++){	assert(srp->fds[i]!=0);    }}    void srp_dump(AFFILE *af){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    for(unsigned int i=0;i<srp->num_raw_files;i++){	fprintf(stderr,"   fds[%d]=%d   pos[%d]=%"I64d"\n",i,srp->fds[i],i,srp->pos[i]);    }    srp_validate(af);    fprintf(stderr,"===================\n");}    static void srp_add_fd(AFFILE *af,int fd){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    srp->num_raw_files++;    srp->fds = (int *)realloc (srp->fds, sizeof (int) * (srp->num_raw_files));    srp->fds[srp->num_raw_files - 1] = fd;    srp->pos = (uint64 *)realloc (srp->pos, sizeof (uint64) * (srp->num_raw_files));    srp->pos[srp->num_raw_files - 1] = 0;}static int split_raw_open_internal(AFFILE *af, uint64 *image_size){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    int fd;    struct stat sb;    fd = open(srp->first_raw_fname, af->openflags|O_BINARY, 0666);    if (fd < 0) {      (*af->error_reporter)("split_raw_open_internal: open(%s): ",af->fname);	return -1;    }    srp->num_raw_files = 1;    srp->fds = (int *)malloc (sizeof (int));    srp->fds[0] = fd;    srp->pos = (uint64 *)malloc (sizeof (uint64));    if (fstat (fd, &sb) != 0) {      (*af->error_reporter)("split_raw_open_internal: fstat(%s): ",af->fname);	close (fd);	return -1;    }    af->maxsize = 0;    /* If there's a next_raw_fname set by the caller of this function, we     * have a split file; otherwise we have one big file.     */    if (srp->next_raw_fname==0) {	(*image_size) = sb.st_size;	return 0;    }	    /* This gets set to 1 the first time we find a file whose size doesn't       match the size of the first file.  If we successfully open a file       when this flag is already 1, then our sanity checks fail. */    int current_file_must_be_last = 0;    do {	if (increment_fname (srp->next_raw_fname) != 0) {	    fprintf (stderr, "split_raw_open_internal: too many files\n");	    errno = EINVAL;	    return -1;	}	fd = open(srp->next_raw_fname,		   af->openflags & O_RDWR ? (O_RDWR|O_BINARY) : (O_RDONLY|O_BINARY));	if (fd < 0) {	    if (errno != ENOENT) {		(af->error_reporter)("split_raw_open_internal errno=%d",errno);		return -1;	    }	    (*image_size) = sb.st_size + af->maxsize * (srp->num_raw_files - 1);	    errno = 0;		// reset errno	    return 0;		// end of files	}	srp_add_fd(af,fd);	if (current_file_must_be_last) {	    fprintf(stderr,		    "split_raw_open_internal: %s exists, "		    "but previous file didn't match expected file size\n",af->fname);	    return -1;	}	/* Set af->maxsize to the size of the first file, but only	   if a second file exists.  If no second file exists, then we want	   to use af->maxsize, which cannot be set until after	   af_open returns.  */	if (!af->maxsize)	    af->maxsize = sb.st_size;	if (fstat (fd, &sb) != 0) {	  (*af->error_reporter)("split_raw_open_internal: fstat(%s): ",af->fname);	    return -1;	}	if ((uint64)sb.st_size != af->maxsize){	    current_file_must_be_last = 1;	}    } while (1);    return -1;}static int split_raw_open(AFFILE *af){    int ret;    af->vnodeprivate = (void *)calloc(sizeof(struct split_raw_private),1);    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    srp->first_raw_fname = strdup (af->fname);    srp->next_raw_fname  = strdup (af->fname);    ret = split_raw_open_internal (af, &(af->image_size));    if (ret != 0) {	split_raw_close (af);	return ret;    }    /* Adaptively find the largest pagesize we can use that fits within maxsize */    af->image_pagesize = 512;    while ((af->image_pagesize < (16 * 1024 * 1024))	   && !(af->maxsize % (af->image_pagesize * 2)))	af->image_pagesize *= 2;    if ((ret == 0) && (af->maxsize % af->image_pagesize!=0)) {	fprintf (stderr,		 "split_raw_open: %s: raw_file_size (%"I64d" not a multiple of pagesize %lu\n",		 af->fname, af->maxsize,af->image_pagesize);	split_raw_close (af);	return -1;    }    return 0;}static int split_raw_vstat(AFFILE *af,struct af_vnode_info *vni){    memset(vni,0,sizeof(*vni));		// clear it

⌨️ 快捷键说明

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