// creates a new file that can be used in an OS byte create_file(dir_entry_t* de, char* filename, byte fn_length, byte* buf) { if(!create_dir_entry(de, filename, fn_length, buf)) { #if DEBUG pmsg("Couldn't create direntry!\r\n"); #endif return 0; } if(!write_dir_entry(de, buf)) { #if DEBUG pmsg("problem writing direntry!\r\n"); #endif return 0; } return 1; }
byte invalidate_dir_entry(dir_entry_t* de, byte* buf) { de->filename[0] = 0xe5; return write_dir_entry(de, buf); }
static block_info_t *write_file(ffs_sort_t *sort, block_info_t *block_info){ FILE *read_file_fp; uint8_t done=0, firstpass=1, *file_buffer; uint16_t unit_flags; uint32_t update_dot=0, pos, remain, remain_dword, prev_extent; int32_t read_size; // // allocate file buffer // if ((file_buffer = (char *)malloc(0x4000)) == NULL) mk_flash_exit("malloc failed: %s\n",strerror(errno)); // // open the file for read // if ((read_file_fp = fopen(sort->host_fullpath,"rb")) == NULL) mk_flash_exit("fopen of %s failed: %s\n",sort->host_fullpath,strerror(errno)); // // check for compressed file. We check for the "FZIP" signature which is offset 1 long into // the compressed file // fseek(read_file_fp, sizeof(f3s_comp_t), SEEK_SET); fread(file_buffer, F3S_COMP_SIG_SIZE, 1, read_file_fp); /* updated by christian to support lzo */ if (memcmp(file_buffer, F3S_FZIP_SIG, F3S_COMP_SIG_SIZE) && memcmp(file_buffer, F3S_FLZO_SIG, F3S_COMP_SIG_SIZE) && memcmp(file_buffer, F3S_FUCL_SIG, F3S_COMP_SIG_SIZE)) sort->status &=~COMPRESSED; else sort->status |=COMPRESSED; // // seek back to the beginning of the file // fseek(read_file_fp, 0L, SEEK_SET); // // write the entry. f3s_dirent_t is used for both files and directory entries. // block_info = write_dir_entry(sort, block_info); if(verbose){ putc(42,debug_fp); fflush(debug_fp); } prev_extent = 0; while(!done){ read_size = block_info->available_space - sizeof(f3s_head_t); if (read_size > MAX_WRITE) read_size = MAX_WRITE; if (read_size <= 0){ unit_flags = ((~F3S_UNIT_MASK | F3S_UNIT_READY) & ~F3S_UNIT_NO_LOGI); block_info = init_block(block_info->block_size, unit_flags); } read_size = block_info->available_space - sizeof(f3s_head_t); if (read_size > MAX_WRITE) read_size = MAX_WRITE; // // a regular file // remain = fread(file_buffer,1,read_size,read_file_fp); // // update 'first' or 'next' extent pointer. First pass requires the 'first' pointer // updated, subsequent extents are 'next' extent pointers. // if (firstpass){ first_file_extent(sort->entry_pos+4, remain, block_info); firstpass = 0; } else { file_extent(prev_extent, remain, block_info); } // // keep a copy of the position of the previous extent // prev_extent = (block_info->block_index * block_info->block_size) + block_info->offset_bottom; // // check whether we've read all that we can read // if (remain < read_size) done = 1; // // verbose display of file being written // if(verbose){ update_dot +=remain; if (update_dot >=MAX_WRITE){ putc(42,debug_fp); fflush(debug_fp); update_dot = 0; } } // // position and write the content of the file to the image file // pos = (block_info->block_index * block_info->block_size) + block_info->offset_top; lseek(flashimage,pos,SEEK_SET); if (write(flashimage,file_buffer,remain) != remain) mk_flash_exit("write failed: %s\n",strerror(errno)); // // must make sure that the offset_top is DWORD aligned // remain_dword = (((remain) + (sizeof(uint32_t)-1))&~(sizeof(uint32_t)-1)); block_info->offset_top += remain_dword; block_info->available_space -= remain_dword; } // //close the file // fclose(read_file_fp); if (verbose) fprintf(debug_fp,"\n"); free(file_buffer); return block_info; }
static block_info_t *write_lnk(ffs_sort_t *sort, block_info_t *block_info){ uint8_t lnk_buffer[F3S_PATH_MAX+1]; uint16_t unit_flags; uint32_t pos, lnk_dword; int32_t lnk_size; struct file_entry *fip = sort->fip; // // write the entry. f3s_dirent_t is used for both files and directory entries. // block_info = write_dir_entry(sort, block_info); // // get the content of the symlink // if(!fip->hostpath || *fip->hostpath == '\0'){ if ((lnk_size = readlink(sort->host_fullpath, lnk_buffer, F3S_PATH_MAX)) == -1) mk_flash_exit("readlink failed: %s\n",strerror(errno)); } else{ strcpy(lnk_buffer, fip->hostpath); lnk_size = strlen(lnk_buffer); } if(verbose){ putc(42,debug_fp); fflush(debug_fp); } if (block_info->available_space < lnk_size + sizeof(f3s_head_t)){ unit_flags = ((~F3S_UNIT_MASK | F3S_UNIT_READY) & ~F3S_UNIT_NO_LOGI); block_info = init_block(block_info->block_size, unit_flags); } // // update 'first' or 'next' extent pointer. First pass requires the 'first' pointer // updated, subsequent extents are 'next' extent pointers. // first_file_extent(sort->entry_pos+4, lnk_size, block_info); // // position and write the content of the file to the image file // pos = (block_info->block_index * block_info->block_size) + block_info->offset_top; lseek(flashimage,pos,SEEK_SET); if (write(flashimage,lnk_buffer,lnk_size) != lnk_size) mk_flash_exit("write failed: %s\n",strerror(errno)); // // must make sure that the offset_top is DWORD aligned // lnk_dword = (((lnk_size) + (sizeof(uint32_t)-1))&~(sizeof(uint32_t)-1)); if (verbose) fprintf(debug_fp,"\n"); block_info->offset_top += lnk_dword; block_info->available_space -= lnk_dword; return block_info; }
static void write_f3s(ffs_sort_t *sort, int block_size){ block_info_t *block_info; uint32_t size_of_entry; ffs_sort_t *sort_temp_ptr; uint16_t unit_flags; // // setup generic buffer // if ((blk_buffer_ptr = (char *)malloc(0x4000)) == NULL) mk_flash_exit("malloc failed: %s\n",strerror(errno)); // // create a temporary file // tmp_name = mk_tmpfile(); if ((flashimage = open(tmp_name,O_BINARY | O_RDWR | O_CREAT | O_TRUNC, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) mk_flash_exit("create of %s failed: %s\n",tmp_name,strerror(errno)); unit_flags = ((~F3S_UNIT_MASK | F3S_UNIT_READY) & ~F3S_UNIT_NO_LOGI); block_info = init_block(block_size, unit_flags); // // first block requires a boot record // write_boot_record (block_info, spare_blocks,sort); // // write the initialized block to the file. each entry will be written // to disk individually. // // check if this entry has been written to the file yet // run through the list until we get to the end // while(sort){ if (!(sort->status & FFS_SORT_ENTRY_SET)){ switch(sort->mode & S_IFMT){ case S_IFDIR: if(verbose) fprintf(debug_fp,"writing directory entry -> %s\n",sort->name); block_info = write_dir_entry(sort, block_info); break; case S_IFREG: if(verbose) fprintf(debug_fp,"writing file entry -> %s ",sort->name); block_info = write_file(sort,block_info); break; case S_IFLNK: if(verbose) fprintf(debug_fp,"writing link entry -> %s ",sort->name); block_info = write_lnk(sort,block_info); break; case S_IFIFO: if(verbose) fprintf(debug_fp,"writing fifo entry -> %s\n",sort->name); block_info = write_dir_entry(sort, block_info); break; } } // // check for a child, only a directory can have a child // if (!sort->child && (sort->mode & (S_IFDIR|S_IFIFO))){ // // directory entry under f3s can not have a NULL first extent. The extent pointer must // refer to an extent that in turn points to 0 sized data. // child_extent(sort,0,block_info); } if (sort->child && (sort->mode & S_IFDIR)){ // //child // if ((sort_temp_ptr = find_child(sort)) == NULL) mk_flash_exit("find_child failed\n"); size_of_entry = sizeof(f3s_dirent_t) + F3S_NAME_ALIGN(strlen(sort_temp_ptr->name)+1) + sizeof(f3s_stat_t); sort_temp_ptr->size_of_entry = size_of_entry; if (block_info->available_space < (size_of_entry + sizeof(f3s_head_t))) block_info = init_block(block_size, unit_flags); child_extent(sort,sort_temp_ptr->size_of_entry,block_info); // //check the mode of our child // switch(sort_temp_ptr->mode & S_IFMT){ case S_IFDIR: if(verbose) fprintf(debug_fp,"writing directory entry -> %s\n",sort_temp_ptr->name); block_info = write_dir_entry(sort_temp_ptr, block_info); break; case S_IFREG: if(verbose) fprintf(debug_fp,"writing file entry -> %s ",sort_temp_ptr->name); block_info = write_file(sort_temp_ptr,block_info); break; case S_IFLNK: if(verbose) fprintf(debug_fp,"writing link entry -> %s ",sort_temp_ptr->name); block_info = write_lnk(sort_temp_ptr,block_info); break; case S_IFIFO: if(verbose) fprintf(debug_fp,"writing FIFO entry -> %s\n",sort_temp_ptr->name); block_info = write_dir_entry(sort_temp_ptr, block_info); break; } } // //check for a sibling // if (sort->sibling){ if ((sort_temp_ptr = find_sibling(sort)) == NULL) mk_flash_exit("find_sibling failed\n"); size_of_entry = sizeof(f3s_dirent_t) + F3S_NAME_ALIGN(strlen(sort_temp_ptr->name)+1) + sizeof(f3s_stat_t); sort_temp_ptr->size_of_entry = size_of_entry; if (block_info->available_space < (size_of_entry + sizeof(f3s_head_t))) block_info = init_block(block_size, unit_flags); sibling_extent(sort,sort_temp_ptr->size_of_entry,block_info); switch(sort_temp_ptr->mode & S_IFMT){ case S_IFDIR: if(verbose) fprintf(debug_fp,"writing directory entry -> %s\n",sort_temp_ptr->name); block_info = write_dir_entry(sort_temp_ptr, block_info); break; case S_IFREG: if(verbose) fprintf(debug_fp,"writing file entry -> %s ",sort_temp_ptr->name); block_info = write_file(sort_temp_ptr,block_info); break; case S_IFLNK: if(verbose) fprintf(debug_fp,"writing link entry -> %s ",sort_temp_ptr->name); block_info = write_lnk(sort_temp_ptr,block_info); break; case S_IFIFO: if(verbose) fprintf(debug_fp,"writing fifo entry -> %s\n",sort_temp_ptr->name); block_info = write_dir_entry(sort_temp_ptr, block_info); break; } } sort=sort->next; } // // write out the rest of the filesystem. This includes the spare block(s) and formatting // additional blocks // spare_block_alloc(block_info); // // free our malloc buffer // free(blk_buffer_ptr); }