示例#1
0
static int afm_open(AFFILE *af)
{
    af->vnodeprivate = (void *)calloc(sizeof(struct afm_private),1);
    struct afm_private *ap = AFM_PRIVATE(af);
    ap->aff = af_open_with(af_filename(af),af->openflags,af->openmode,&vnode_aff);

    if(ap->aff==0){			// open failed?
	afm_close(af);
	return -1;
    }
    ap->aff->parent = af;

    /* If this is a new file, write out the default split raw extension */
    if(af->exists == 0){
	if(afm_create(af)) return -1;
    }

    /* If this is an old file, read the image_pagesize */
    if(af->exists){
	af->image_pagesize = ap->aff->image_pagesize;
    }

    /* Read the split raw extension */
    char raw_file_extension[4];
    size_t  len=3;				// don't overwrite the NUL

    memset(raw_file_extension,0,sizeof(raw_file_extension));
    if (af_get_seg(ap->aff,AF_RAW_IMAGE_FILE_EXTENSION,0,(unsigned char *)raw_file_extension,&len)) {
	(*af->error_reporter)("afm_open: %s: %s segment missing or too large\n",
			      af_filename(af),AF_RAW_IMAGE_FILE_EXTENSION);
	afm_close(af);
	return -1;
    }
    if(invalid_extension_char(raw_file_extension,len)){
	(*af->error_reporter)("afm_open: file extension contains invalid character\n",
		 af->fname, AF_RAW_IMAGE_FILE_EXTENSION);
	afm_close(af);
	return -1;
    }

    /* Now open the splitraw file */
    char *sr_filename = strdup(af_filename(af));
    char *ext = strrchr(sr_filename,'.');
    if(!ext){
	(*af->error_reporter)("afm_open: cannot find extension in '%s'",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }
    ext++;				// skip past '.'
    if(strlen(ext) != strlen(raw_file_extension)){
	(*af->error_reporter)("afm_open: file extension in '%s' too short",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }

    strcpy(ext,raw_file_extension);
    ap->sr  = af_open_with(sr_filename,af->openflags,af->openmode,&vnode_split_raw);
    if(ap->sr==0){
	(*af->error_reporter)("afm_open: could not open '%s'",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }
    ap->sr->parent = af;
    free(sr_filename);

    /* Additional setup will happen first time a data read/write call is made
     * by the function afm_read_write_setup().
     * This allows a new file to be created with af_open() and then to have
     * the parameters set with af_update_seg() calls, yet the split_raw
     * implementation gets the proper settings
     */
    return 0;
}
示例#2
0
/* Add a file to the AFF system.
 * if fname==0, create a new one and copy over the relevant metadata...
 */
static int afd_add_file(AFFILE *af,const char *fname_)
{
    struct afd_private *ap = AFD_PRIVATE(af);
    const char *segs_to_copy[] = {AF_BADFLAG,
				  AF_CASE_NUM,
				  AF_IMAGE_GID,
				  AF_ACQUISITION_ISO_COUNTRY,
				  AF_ACQUISITION_COMMAND_LINE,
				  AF_ACQUISITION_DATE,
				  AF_ACQUISITION_NOTES,
				  AF_ACQUISITION_DEVICE,
				  AF_ACQUISITION_TECHNICIAN,
				  AF_DEVICE_MANUFACTURER,
				  AF_DEVICE_MODEL,
				  AF_DEVICE_SN,
				  AF_DEVICE_FIRMWARE,
				  AF_DEVICE_SOURCE,
				  AF_CYLINDERS,
				  AF_HEADS,
				  AF_SECTORS_PER_TRACK,
				  AF_LBA_SIZE,
				  AF_HPA_PRESENT,
				  AF_DCO_PRESENT,
				  AF_LOCATION_IN_COMPUTER,
				  AF_DEVICE_CAPABILITIES,
				  0};

    char fname[MAXPATHLEN+1];
    memset(fname,0,sizeof(fname));
    if(fname_){
	strlcpy(fname,fname_,sizeof(fname));
    }
    else {
	aff_filename(af,fname,sizeof(fname),ap->num_afs);
    }

    int new_file = access(fname,F_OK)!=0;	// Is this a new file?

    AFFILE *af2 = af_open(fname,af->openflags|AF_NO_CRYPTO,af->openmode); 
    if(af2==0){
	(*af->error_reporter)("open(%s,%d,%d) failed: %s\n",
			      fname,af->openflags,af->openmode,strerror(errno));
	return -1;			// this is bad
    }

    ap->num_afs += 1;
    ap->afs = (AFFILE **)realloc(ap->afs,sizeof(AFFILE *) * ap->num_afs);
    ap->afs[ap->num_afs-1] = af2;

    if(new_file){
	/* Copy over configuration from AFD vnode*/
	af_enable_compression(af2,af->compression_type,af->compression_level);
	af_set_pagesize(af2,af->image_pagesize);		//
	af_set_sectorsize(af2,af->image_sectorsize);
	af_update_seg(af,AF_AFF_FILE_TYPE,0,(const u_char *)"AFD",3);
	
	/* If this is the second file, copy over additional metadata from first... */
	if(ap->num_afs>1){
	    AFFILE *af0 = ap->afs[0];
	    memcpy(af2->badflag,af0->badflag,af->image_sectorsize);
	    af2->bytes_memcpy += af->image_sectorsize;
	    
	    for(const char **segname=segs_to_copy;*segname;segname++){
		unsigned char data[65536];	// big enough for most metadata
		size_t datalen = sizeof(data);
		unsigned long arg=0;
		
		if(af_get_seg(af0,*segname,&arg,data,&datalen)==0){
		    int r = af_update_seg(af2,*segname,arg,data,datalen);
		    if(r!=0){
			(*af->error_reporter)("afd_add_file: could not update %s in %s (r=%d)",
					      *segname,af_filename(af2),r);
		    }
		}
	    }
	}
    }
    
    return 0;
}
示例#3
0
/*  afm_split_raw_setup:
 * Sets up the parameters of the split-raw by reading from the metadata file.
 * The advantage of doing it this way is that a new file can be opened,
 * the metadata parmeters set, and then an af_write() call made, and the values.
 * get copied.
 */
static int afm_split_raw_setup(AFFILE *af)
{
    struct afm_private *ap = AFM_PRIVATE(af);
    if(ap->sr_initialized) return 0;		// already setup

    /* The size of AF_PAGES_PER_RAW_IMAGE_FILE indicates whether the file is split.
     * If it is not present, or if it is 0-length, assume that the file is not split.
     */
    uint64_t pages_per_file = 0;
    size_t len = 0;
    if (af_get_seg(ap->aff,AF_PAGES_PER_RAW_IMAGE_FILE,0,0,&len)) {

	/* Not in file; put it there based on maxsize and image_pagesize,
	 * both of which better be set at this point
	 */
	if (af->image_pagesize < 1) {
	    (*af->error_reporter)("afm_split_raw_setup: image_pagesize==0\n");
	    return -1;
	}
	if (af->maxsize % af->image_pagesize) {
	    (*af->error_reporter)("afm_split_raw_setup: maxsize (%"I64d") "
				  "not a multiple of image_pagesize (%d)\n",
				  af->maxsize,af->image_pagesize);
	    return -1;
	}
	pages_per_file = af->maxsize / af->image_pagesize;
	if (af_update_segq (af, AF_PAGES_PER_RAW_IMAGE_FILE, pages_per_file)) {
	    (*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n",
				  af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE);
	    return -1;
	}
    }

    /* Now, read the segment (which might have just been put there) and set up the split_raw file */
    if(af_get_segq(af,AF_PAGES_PER_RAW_IMAGE_FILE,(int64_t *)&pages_per_file)){
	(*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n",
			      af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE);
	return -1;
    }

    /* Verify that splitraw's notion of the rawfilesize is the same as the
     * metadata's notion if the AFF image_size has been set
     */
    if (ap->aff->image_size && ap->aff->image_size != ap->sr->image_size) {
	(*af->error_reporter)("afm_split_raw_setup: internal error. "
			      "AFF image_size %"I64d" != SR image_size %"I64d"\n",
			      ap->aff->image_size,ap->sr->image_size);
	return -1;
    }

    /* Uses pages_per_file to set the maxsize of the split_raw if it hasn't been set yet*/
    if(ap->sr->maxsize==0){
	ap->sr->maxsize = pages_per_file * af->image_pagesize;
    }

    /* Verify that the parameters make sense */
    if (ap->sr->maxsize != (pages_per_file * af->image_pagesize) && pages_per_file>0) {
	(*af->error_reporter)("afm_split_raw_setup: %s: per size indicated by metadata (%d * %d) "
			      "doesn't match maxsize (%"I64d")\n",
			      af_filename(af),pages_per_file,af->image_pagesize,ap->sr->maxsize);
	return -1;
    }

    /* Push down the image_pagesize from the AFM to the split_raw */
    uint32_t image_pagesize = af->image_pagesize; // default to what's in memory
    af_get_seg(af,AF_PAGESIZE,&image_pagesize,0,0); // get from the AFF file if possible
    ap->sr->image_pagesize = af->image_pagesize; // overwrite the default with what the AFM file

    ap->sr_initialized = 1;
    return 0;
}