static int evd_open(AFFILE *af) { /* If we reach here, we must be opening an E01 file. * Try to open all Enn files until we can't find them anymore. */ char buf[MAXPATHLEN+1]; strcpy(buf,af_filename(af)); // get the filename /* check extension */ char *ext = buf+strlen(buf)-3; assert(ext > buf && !strncmp(ext, "E01", 3)); /* Allocate our private storage */ af->vnodeprivate = (void *)calloc(1,sizeof(struct evd_private)); struct evd_private *ed = EVD_PRIVATE(af); ed->evfs = (AFFILE **)malloc(0); /* Now open all of the files until as high as .ZZZ */ for (int i = 1; i <= 99; i++) { sprintf(ext+1,"%02d",i); if(access(buf,R_OK)!=0) break; // file can't be read AFFILE *en = af_open_with(buf,af->openflags,af->openmode,&vnode_evf); if(!en) break; // this file doens't exist evd_add_file(af,en); // add to our array } for (int i = 4*26*26; i <= 26*26*26; i++) { sprintf(ext, "%c%c%c", i/26/26%26+'A', i/26%26+'A', i%26+'A'); if(access(buf,R_OK)!=0) break; // file can't be read AFFILE *en = af_open_with(buf,af->openflags,af->openmode,&vnode_evf); if(!en) break; // this file doens't exist evd_add_file(af,en); // add to our array } /* Now that everything is opened, lets validate each file and set the chunk_start pointers */ struct evf_private *ef0 = EVF_PRIVATE(ed->evfs[0]); if(ef0->chunk_size==0){ // E01 file didn't have a volume section... evd_close(af); // free the stuff return -1; // } /* Set the chunk sizes and offsets in all of the other files */ for(unsigned int i=1;i<ed->num_evfs;i++){ struct evf_private *ef_this = EVF_PRIVATE(ed->evfs[i]); struct evf_private *ef_prev = EVF_PRIVATE(ed->evfs[i-1]); ef_this->chunk_size = ef0->chunk_size; ef_this->chunk_start = ef_prev->chunk_start + ef_prev->table_section->chunk_count; } af->image_pagesize = ed->evfs[0]->image_pagesize; return 0; // "we were successful" }
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 } /* 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)==1 ){ return af_open_with(filename,flags,mode,af_vnode_array[i]); } } return 0; // can't figure it out. }
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 must 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 ){ AFFILE *af = af_open_with(filename,flags,mode,af_vnode_array[i]); return af; } } errno = EINVAL; if(exists) errno = ENOENT; return 0; // can't figure it out; must be an invalid extension }
int fix(const char *infile) { char buf[1024]; int flags = (opt_fix ? O_RDWR : O_RDONLY) | O_BINARY; switch(af_identify_file_type(infile,1)){ case AF_IDENTIFY_ERR: perror(infile); return 0; default: fprintf(stderr,"%s is not an AFF file\n",infile); return 0; case AF_IDENTIFY_AFF: break; } printf("%s ",infile); int r=0; /* First see if the if the file begins with an AFF flag */ int fd = open(infile,flags,0666); if(fd<0) err(1,"fopen(%s)",infile); if(read(fd,buf,strlen(AF_HEADER)+1)!=strlen(AF_HEADER)+1) err(1,"can't read AFF file header. Stop."); if(strcmp(buf,AF_HEADER)!=0) err(1,"%s does not begin with an AF_HEADER. Stop.",infile); if(read(fd,buf,strlen(AF_SEGHEAD)+1)!=strlen(AF_SEGHEAD)+1) err(1,"Can't read AF_SEGHEAD after AF_HEADER. Stop."); if(strcmp(buf,AF_SEGHEAD)!=0) err(1,"%s does not have an AF_SEGHEAD after AF_SEGEADER. Stop.",infile); /* Figure out length */ off_t len = lseek(fd,0,SEEK_END); if(len<0) err(1,"Can't seek to end of %s. Stop.",infile); close(fd); AFFILE *af = af_open_with(infile,AF_HALF_OPEN|flags,0,&vnode_aff); printf("Scanning AFF file...\n"); r = (*af->v->open)(af); /* See if we can build a TOC */ if(r<0){ printf("AFF file corrupt at %"I64d" out of %"I64d" (%"I64d" bytes from end)\n", ftello(af->aseg),(int64_t)len,len-ftello(af->aseg)); if(opt_fix){ printf("Truncating... %d \n",fileno(af->aseg)); if(ftruncate(fileno(af->aseg),ftello(af->aseg))){ err(1,"ftruncate"); } } } /* See if it has a GID or an encrypted GID */ if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0 && af_get_seg(af,AF_IMAGE_GID AF_AES256_SUFFIX,0,0,0)!=0){ printf("AFF file is missing a GID. "); if(opt_fix){ printf("Making one..."); if(af_make_gid(af)<0) af_err(1,"af_make_gid"); } putchar('\n'); } af_close(af); return 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; }