Example #1
0
/* find the given segment and return 0 if found.
 * Leave the file pointer positioned at the start of the segment.
 * Return -1 if segment is not found, and leave pointer at the end
 */
int	aff_find_seg(AFFILE *af,const char *segname,
		    uint32_t *arg,
		    size_t *datasize,
		    size_t *segsize)
{
    char   next_segment_name[AF_MAX_NAME_LEN];
    size_t next_segsize = 0;
    size_t next_datasize = 0;
    uint32_t next_arg;

    /* Try to use the TOC to find the segment in question */
    struct aff_toc_mem *adm = aff_toc(af,segname);
    if(adm){
	if(datasize==0 && segsize==0 && arg==0){
	    /* User was just probing to see if it was present. And it is! */
	    return 0;
	}
	fseeko(af->aseg,adm->offset,SEEK_SET);
    }
    else {
	af_rewind_seg(af);
    }
    while(af_probe_next_seg(af,next_segment_name,sizeof(next_segment_name),
			    &next_arg,&next_datasize,&next_segsize,1)==0){
	if(strcmp(next_segment_name,segname)==0){	// found the segment!
	    if(datasize) *datasize = next_datasize;
	    if(segsize)  *segsize  = next_segsize;
	    if(arg)      *arg      = next_arg;
	    return 0;			// return the info
	}
	fseeko(af->aseg,next_segsize,SEEK_CUR);	// skip the segment
    }
    return -1;				// couldn't find segment
}
Example #2
0
static int evd_rewind_seg(AFFILE *af)
{
    struct evd_private *ep = EVD_PRIVATE(af);
    ep->cur_file = 0;
    if(ep->num_evfs>0){
	return af_rewind_seg(ep->evfs[0]);
    }
    return 0;				// no files, so nothing to rewind
}
Example #3
0
/* Rewind all of the segments */
static int afd_rewind_seg(AFFILE *af)
{
    struct afd_private *ap = AFD_PRIVATE(af);
    ap->cur_file = 0;
    for(int i=0;i<ap->num_afs;i++){
	af_rewind_seg(ap->afs[i]);
    }
    return 0;		
}
Example #4
0
void affstats(const char *fname)
{
    AFFILE *af = af_open(fname,O_RDONLY,0);
    if(!af) af_err(1,"af_open(%s)",fname);

    printf("%s\t",fname);

    uint32_t segsize=0;

    int64_t imagesize=0;
    int64_t blanksectors=0;
    int64_t badsectors=0;
    af_get_segq(af,AF_IMAGESIZE,&imagesize);
    if(af_get_seg(af,AF_PAGESIZE,&segsize,0,0)){
	af_get_seg(af,AF_SEGSIZE_D,&segsize,0,0); // check for oldstype
    }
    af_get_segq(af,AF_BADSECTORS,&badsectors);
    af_get_segq(af,AF_BLANKSECTORS,&blanksectors);

    print_size(imagesize);
    printf("\t");
    fflush(stdout);

    int64_t compressed_bytes = 0;
    int64_t uncompressed_bytes = 0;

    /* Now read through all of the segments and count the number of
     * data segments. We know the uncompressed size...
     */
    af_rewind_seg(af);
    char segname[AF_MAX_NAME_LEN+1];
    size_t datalen;
    while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){
	int64_t page_num = af_segname_page_number(segname);
	if(page_num>=0){
	    compressed_bytes += datalen;
	    uncompressed_bytes += segsize;
	}
    }
    if(uncompressed_bytes > imagesize) uncompressed_bytes = imagesize;

    print_size(compressed_bytes);
    printf("\t");
    print_size(uncompressed_bytes);
    printf(" %" I64d " %" I64d,blanksectors,badsectors);
    putchar('\n');
    
    
}
Example #5
0
static PyObject *affile_get_seg_names(affile *self) {
	PyObject *headers, *tmp;
	char segname[AF_MAX_NAME_LEN];

    af_rewind_seg(self->af);
    headers = PyList_New(0);

    while(af_get_next_seg(self->af, segname, sizeof(segname), 0, 0, 0) == 0){
        tmp = PyString_FromString(segname);
        PyList_Append(headers, tmp);
        Py_DECREF(tmp);
    }

    return headers;
}
Example #6
0
static int afd_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg,
			unsigned char *data,size_t *datalen_)
{
    /* See if there are any more in the current segment */
    struct afd_private *ap = AFD_PRIVATE(af);
    while (ap->cur_file < ap->num_afs) {
	int r = af_get_next_seg(ap->afs[ap->cur_file],segname,segname_len,arg,data,datalen_);
	if(r!=AF_ERROR_EOF){		// if it is not EOF
	    return r;
	}
	ap->cur_file++;			// advance to the next file
	if(ap->cur_file < ap->num_afs){	// rewind it to the beginning
	    af_rewind_seg(ap->afs[ap->cur_file]);
	}
    } while(ap->cur_file < ap->num_afs);
    return AF_ERROR_EOF;		// really made it to the end
}
Example #7
0
/* af_read_sizes:
 * Get the page sizes if they are set in the file.
 */
void af_read_sizes(AFFILE *af)
{
    af_get_seg(af,AF_SECTORSIZE,&af->image_sectorsize,0,0);
    if(af->image_sectorsize==0) af->image_sectorsize = 512; // reasonable default

    if(af_get_seg(af,AF_PAGESIZE,&af->image_pagesize,0,0)){
	af_get_seg(af,AF_SEGSIZE_D,&af->image_pagesize,0,0); // try old name
    }

    /* Read the badflag if it is present */
    size_t sectorsize = af->image_sectorsize;
    if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize);
    if(af_get_seg(af,AF_BADFLAG,0,af->badflag,(size_t *)&sectorsize)==0){
	af->badflag_set = 1;
    }

    /* Read the image file segment if it is present. 
     * If it isn't, scan through the disk image to figure out the size of the disk image.
     */

    if(af_get_segq(af,AF_IMAGESIZE,(int64_t *)&af->image_size)){

	/* Calculate the imagesize by scanning all of the pages that are in
	 * the disk image and finding the highest page number.
	 * Then read that page to find the last allocated byte.
	 */
	char segname[AF_MAX_NAME_LEN];
	size_t datalen = 0;
	af_rewind_seg(af);		//  start at the beginning
	int64_t highest_page_number = 0;
	while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){
	    if(segname[0]==0) continue;	// ignore sector
	    int64_t pagenum = af_segname_page_number(segname);
	    if(pagenum > highest_page_number) highest_page_number = pagenum;
	}
	size_t highest_page_len = 0;
	if(af_get_page(af,highest_page_number,0,&highest_page_len)==0){
	    af->image_size = af->image_pagesize * highest_page_number + highest_page_len;
	}
    }
    af->image_size_in_file = af->image_size;
}
Example #8
0
static int evd_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg,
			unsigned char *data,size_t *datalen_)
{
    /* See if there are any more in the current segment */
    struct evd_private *ep = EVD_PRIVATE(af);
    if(ep->num_evfs==0) return AF_ERROR_EOF; // no files, so we are at the end
    do {
	int r = af_get_next_seg(ep->evfs[ep->cur_file],segname,segname_len,arg,data,datalen_);
	if(r!=AF_ERROR_EOF){		// if it is not EOF
	    return r;
	}
	if(ep->cur_file < ep->num_evfs-1){
	    ep->cur_file++;		// go to the next file if there is one
	    if(ep->cur_file < ep->num_evfs){
		af_rewind_seg(ep->evfs[ep->cur_file]); // and rewind that file
	    }
	}
    } while(ep->cur_file < ep->num_evfs-1);
    return AF_ERROR_EOF;		// really made it to the end
}
Example #9
0
Attributes	AffNode::_attributes()
{
    Attributes 	vmap;
    struct af_vnode_info vni;
    unsigned long total_segs = 0;
    unsigned long total_pages = 0;
    unsigned long total_hashes = 0;
    unsigned long total_signatures =0;
    unsigned long total_nulls = 0;

    vmap["orignal path"] =  new Variant(this->originalPath);
    AFFILE*  affile = af_open(this->originalPath.c_str(), O_RDONLY, 0);
    if (affile)
    {
        vmap["dump type"] = new Variant(std::string(af_identify_file_name(this->originalPath.c_str(), 1)));
        if (af_vstat(affile, &vni) == 0)
        {
            if (vni.segment_count_encrypted > 0 || vni.segment_count_signed > 0)
            {
                vmap["encrypted segments"] = new Variant(vni.segment_count_encrypted);
                vmap["signed segments"] = new Variant(vni.segment_count_signed);
            }
            vector <string> segments;
            char segname[AF_MAX_NAME_LEN];
            af_rewind_seg(affile);
            int64_t total_datalen = 0;
            size_t total_segname_len = 0;
            size_t datalen = 0;
            int aes_segs=0;
            while(af_get_next_seg(affile, segname, sizeof(segname), 0, 0, &datalen)==0)
            {
                total_segs++;
                total_datalen += datalen;
                total_segname_len += strlen(segname);
                if(segname[0]==0)
                    total_nulls++;

                char hash[64];
                int64_t page_num = af_segname_page_number(segname);
                int64_t hash_num = af_segname_hash_page_number(segname,hash,sizeof(hash));
                if(page_num>=0)
                    total_pages++;
                if(hash_num>=0)
                    total_hashes++;
                if(strstr(segname,AF_SIG256_SUFFIX))
                    total_signatures++;
                if(strstr(segname,AF_AES256_SUFFIX))
                    aes_segs++;
                if((page_num>=0||hash_num>=0))
                    continue;
                if(af_is_encrypted_segment(segname))
                    continue;
                this->addSegmentAttribute(&vmap, affile, segname);
            }
            vmap["Total segments"] = new Variant((uint64_t)total_segs);
            vmap["Total segments real"] = new Variant((uint64_t)(total_segs - total_nulls));
            if (aes_segs)
                vmap["Encrypted segments"] = new Variant(aes_segs);
            vmap["Page segments"] = new Variant((uint64_t)total_pages);
            vmap["Hash segments"] = new Variant((uint64_t)total_hashes);
            vmap["Signature segments"] = new Variant((uint64_t)total_signatures);
            vmap["Null segments"] = new Variant((uint64_t)total_nulls);
            vmap["Total data bytes"] = new Variant((uint64_t)total_datalen);
        }

    }

    af_close(affile);

    return vmap;
}
Example #10
0
/* afm_rewind_seg:
 * Rewind both the AFF file and the split_raw file(s)
 */
static int afm_rewind_seg(AFFILE *af)
{
    struct afm_private *ap = AFM_PRIVATE(af);
    if ( af_rewind_seg(ap->aff) ) return -1; // that's bad
    return af_rewind_seg(ap->sr);	// and rewind the splitraw
}
Example #11
0
static int aff_update_seg(AFFILE *af, const char *name,
		    uint32_t arg,const u_char *value,uint32_t vallen)
{
    char   next_segment_name[AF_MAX_NAME_LEN];
    size_t next_segsize = 0;
    size_t next_datasize = 0;

    /* if we are updating with a different size,
     * remember the location and size of the AF_IGNORE segment that
     * has the smallest size that is >= strlen(name)+vallen
     */
    size_t size_needed = vallen+aff_segment_overhead(name);
    size_t size_closest = 0;
    uint64_t         loc_closest = 0;
    struct aff_toc_mem *adm = aff_toc(af,name);
       
    if(af_trace) fprintf(af_trace,"aff_update_seg(name=%s,arg=%"PRIu32",vallen=%u)\n",name,arg,vallen);


    if(adm){
	/* Segment is in the TOC; seek to it */
	fseeko(af->aseg,adm->offset,SEEK_SET);
    }
    else {
	/* Otherwise, go to the beginning of the file and try to find a suitable hole
	 * TK: This could be made significantly faster by just scanning the TOC for a hole.
	 */
	af_rewind_seg(af);			// start at the beginning
    }

    while(af_probe_next_seg(af,next_segment_name,sizeof(next_segment_name),0,&next_datasize,&next_segsize,1)==0){
	/* Remember this information */
	uint64_t next_segment_loc = ftello(af->aseg);
#ifdef DEBUG2
	fprintf(stderr,"  next_segment_name=%s next_datasize=%d next_segsize=%d next_segment_loc=%qd\n",
		next_segment_name, next_datasize, next_segsize,next_segment_loc);
#endif
	if(strcmp(next_segment_name,name)==0){	// found the segment
	    if(next_datasize == vallen){        // Does it exactly fit?
		int r = aff_write_seg(af,name,arg,value,vallen); // Yes, just write in place!
		return r;
	    }

	    //printf("** Segment '%s' doesn't fit at %qd; invalidating.\n",name,ftello(af->aseg));
	    aff_write_ignore(af,next_datasize+strlen(name));

	    /* If we are in random mode, jump back to the beginning of the file.
	     * This does a good job filling in the holes.
	     */
	    if(af->random_access){
		af_rewind_seg(af);
		continue;
	    }

	    /* Otherwise just go to the end. Experience has shown that sequential access
	     * tends not to generate holes.
	     */
	    fseeko(af->aseg,(uint64_t)0,SEEK_END);              // go to the end of the file
	    break;			// and exit this loop
	    
	}

	if((next_segment_name[0]==0) && (next_datasize>=size_needed)){
	    //printf("   >> %d byte blank\n",next_datasize);
	}

	/* If this is an AF_IGNORE, see if it is a close match */
	if((next_segment_name[0]==AF_IGNORE[0]) &&
	   (next_datasize>=size_needed) &&
	   ((next_datasize<size_closest || size_closest==0)) &&
	   ((next_datasize<1024 && size_needed<1024) || (next_datasize>=1024 && size_needed>=1024))){
	    size_closest = next_datasize;
	    loc_closest  = next_segment_loc;
	}
	fseeko(af->aseg,next_segsize,SEEK_CUR); // skip this segment
    }

    /* Ready to write */
    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.
	 */
	//printf("*** Squeezing it in at %qd. name=%s. vallen=%d size_closest=%d\n",loc_closest,name,vallen,size_closest);

	fseeko(af->aseg,loc_closest,SEEK_SET); // move to the location
	aff_write_seg(af,name,arg,value,vallen); // write the new segment
	
	size_t newsize = size_closest - vallen - aff_segment_overhead(0) - strlen(name);
	aff_write_ignore(af,newsize); // write the smaller ignore
	return 0;
    }
    /* If we reach here we are positioned at the end of the file. */
    /* If the last segment is an ignore, truncate the file before writing */
    while(af_truncate_blank(af)==0){
	/* Keep truncating until there is nothing left */
    }
    //printf("*** appending '%s' bytes=%d to the end\n",name,vallen);
    fseeko(af->aseg,0L,SEEK_END);		// move back to the end of the file 
    return aff_write_seg(af,name,arg,value,vallen); // just write at the end
}