/* * This this doesn't do and i have no intention of adding * 1) flags * 2) checking if the file is already open * 3) open file under different fs * a) files have acess to lfs infoz they should have an fs field */ devcall lfsOpen( struct dentry* devptr, char* path, char* mode){ printf("path: %s\n", path); struct lflcblk* lfptr; /* pointer to open file table entry */ struct ext2_dir_entry_2* newEnt; /* pointer to new entry */ int lfnext; /* minor number of next dev */ int i; /* index */ // int mbits; /* mode bits */ int lastDir; /* location of last '/' */ char* filename; char* fpath; for ( i = 0; i < Nlfl; i++){ lfptr = &lfltab[i]; if(lfptr->lfstate == LF_FREE){ break; } } if( i == Nlfl ) return SYSERR; filename = path; while( 1 ){ fpath = filename; filename = strchr( filename, '/' ); if( !filename ) break; filename++; } int len = strnlen( fpath, 1500 ); if( len > LF_NAME_LEN ) return SYSERR; char name[len]; strncpy( name, fpath, len ); char tmp = *fpath; *fpath = '\0'; // without this i gain an extra '/' name[len] = 0; printf("FS: %x, Path: %s, Name: %s\n", Lf_data.xinufs, path, name); lfptr->dir = ext2_get_dirent_from_path( Lf_data.xinufs, path, name); print_dirent(lfptr->dir); lfptr->lfstate = LF_USED; print_dirent( lfptr->dir); // restore the string to what the caller expects *fpath = tmp; return lfptr->lfdev; }
void checkandfix(uint8_t *image_buf, struct bpb33* bpb, int *refcount) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { //to print directory use print_dirent (change to get_dirent when done) uint16_t followclust = print_dirent(dirent, 0, image_buf, bpb, refcount); //char buffer[MAXFILENAME]; //uint16_t followclust = get_dirent(dirent, buffer); if (is_valid_cluster(followclust, bpb)) { refcount[followclust]++; //updating refcount for index of current cluster printf("refcount is: %d, followclust is: %d\n\n", refcount[followclust], followclust); follow_dir(followclust, 1, image_buf, bpb, refcount); } //this is where the magic happens...or in print_dirent? I'd rather do // it here dirent++; } }
/************FOLLOW_DIR***************/ void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb, int* refcount) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); //can't we just use int numDirEntries = bpb->RootDirEnts?? int i = 0; for ( ; i < numDirEntries; i++) { // char buffer[MAXFILENAME]; // uint16_t followclust = get_dirent(dirent, buffer); uint16_t followclust = print_dirent(dirent, indent, image_buf, bpb, refcount); //changed to print as follow_dir is called if (followclust) { refcount[followclust]++; follow_dir(followclust, indent+1, image_buf, bpb, refcount); } dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
void follow_dir(char* filename, uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); for ( int i=0; i < numDirEntries; i++) { uint16_t followclust = print_dirent(filename, dirent, indent); int count = -1; if (followclust!= 0) { count=compare(filename, followclust,dirent,image_buf,bpb); } else { } //printf("count: %i\n", count); if (followclust !=0) follow_dir(filename, followclust, indent+1, image_buf, bpb); dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); printf("The address of the first dirent is: %lu\n", dirent); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(dirent, 0); if (is_valid_cluster(followclust, bpb)) follow_dir(followclust, 1, image_buf, bpb); dirent++; } }
int main(int ac, const char **av) { char *dname; assert(ac == 1); assert(asprintf(&dname, "%s.test.tmp.dir", av[0]) > 0); assert(!mkdir(dname, 0700)); assert(!chdir(dname)); (void) close(0); assert(!creat(fname, 0600)); assert(!close(0)); assert(!open(".", O_RDONLY | O_DIRECTORY)); unsigned long count = (unsigned long) 0xfacefeeddeadbeefULL; long rc = syscall(__NR_getdents64, (long) 0xdefacedffffffffULL, NULL, count); printf("getdents64(-1, NULL, %u) = %ld %s (%m)\n", (unsigned) count, rc, errno2name()); count = (unsigned long) 0xfacefeed00000000ULL | sizeof(buf); while ((rc = syscall(__NR_getdents64, 0, buf, count))) { kernel_dirent64 *d; long i; if (rc < 0) perror_msg_and_skip("getdents64"); printf("getdents64(0, ["); for (i = 0; i < rc; i += d->d_reclen) { d = (kernel_dirent64 *) &buf[i]; if (i) printf(", "); print_dirent(d); } printf("], %u) = %ld\n", (unsigned) count, rc); } printf("getdents64(0, [], %u) = 0\n", (unsigned) count); puts("+++ exited with 0 +++"); assert(!unlink(fname)); assert(!chdir("..")); assert(!rmdir(dname)); return 0; }
void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(dirent, 0); if (is_valid_cluster(followclust, bpb)){ //dirent->deReferenceCount=1; follow_dir(followclust, 1, image_buf, bpb); } dirent++; } //printf("ReferenceCount= %d\n", dirent->deReferenceCount); }
void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); int i = 0; for ( ; i < numDirEntries; i++) { uint16_t followclust = print_dirent(dirent, indent); if (followclust) follow_dir(followclust, indent+1, image_buf, bpb); dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
void traverse_root(char * filename, uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry *dirent = (struct direntry*)cluster_to_addr(cluster, image_buf, bpb); int i = 0; for ( ; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = print_dirent(filename,dirent, 0); if (is_valid_cluster(followclust, bpb)) { follow_dir(filename, followclust, 1, image_buf, bpb); printf("Cluster is valid\n"); } dirent++; } printf("finished going through stuff\n"); // find_orphans(image_buf, bpb); }
int_32 Shell_dirent(int_32 argc, char_ptr argv[] ) { /* Body */ boolean print_usage, shorthelp = FALSE; int_32 return_code = SHELL_EXIT_SUCCESS; uint_32 sector,num_sectors; int_32 offset; MQX_FILE_PTR fd, fs; uint_32 e; uchar_ptr buffer; MFS_DIR_ENTRY_PTR dirents; print_usage = Shell_check_help_request(argc, argv, &shorthelp ); if (!print_usage) { if ((argc < 2) || (argc > 4)) { printf("Error, invalid number of parameters\n"); return_code = SHELL_EXIT_ERROR; print_usage=TRUE; } else if ( !Shell_parse_uint_32(argv[1], (uint_32_ptr) &offset )) { printf("Error, invalid length\n"); return_code = SHELL_EXIT_ERROR; print_usage=TRUE; } else { num_sectors = 1; if (argc >= 3) { if ( !Shell_parse_uint_32(argv[2], (uint_32_ptr) &num_sectors )) { num_sectors = 1; } } if (argc == 4) { fd = fopen(argv[3], "r"); if (!fd) { printf("Error, unable to open file %s.\n", argv[1] ); return_code = SHELL_EXIT_ERROR; } } else { fs = Shell_get_current_filesystem(argv); _io_ioctl(fs, IO_IOCTL_GET_DEVICE_HANDLE, &fd); } if (fd) { buffer = _mem_alloc(SECTOR_SIZE); if (buffer) { for(sector=0;sector<num_sectors;sector++) { if (fseek(fd, offset+sector, IO_SEEK_SET) == IO_ERROR) { printf("Error, unable to seek to sector %s.\n", argv[1] ); return_code = SHELL_EXIT_ERROR; } else if (_io_read(fd, (char_ptr) buffer, 1) !=1) { printf("Error, unable to read sector %s.\n", argv[1] ); return_code = SHELL_EXIT_ERROR; } else if (!is_zero(buffer, SECTOR_SIZE)) { printf("\nEntry # %d",offset+sector); dirents = (MFS_DIR_ENTRY_PTR) buffer; for (e=0;e<DIRENTS_PER_SECTOR;e++) { print_dirent(&dirents[e]); } printf("\n"); } } _mem_free(buffer); } else { printf("Error, unable to allocate sector buffer.\n" ); return_code = SHELL_EXIT_ERROR; } if (argc >= 4) { fclose(fd); } } } } if (print_usage) { if (shorthelp) { printf("%s <sector> [<device>]\n", argv[0]); } else { printf("Usage: %s <sector> [<device>]\n", argv[0]); printf(" <sector> = sector number\n"); printf(" <device> = low level device\n"); } } return return_code; } /* Endbody */
int main(int argc,char **argv) { struct libmsfat_disk_locations_and_info locinfo; struct libmsfat_context_t *msfatctx = NULL; uint32_t first_lba=0,size_lba=0; const char *s_partition = NULL; const char *s_cluster = NULL; libmsfat_cluster_t cluster=0; const char *s_image = NULL; const char *s_out = NULL; unsigned char nohex = 0; int i,fd,out_fd=-1; for (i=1; i < argc;) { const char *a = argv[i++]; if (*a == '-') { do { a++; } while (*a == '-'); if (!strcmp(a,"image")) { s_image = argv[i++]; } else if (!strcmp(a,"partition")) { s_partition = argv[i++]; } else if (!strcmp(a,"cluster")) { s_cluster = argv[i++]; } else if (!strcmp(a,"nohex")) { nohex = 1; } else if (!strcmp(a,"o") || !strcmp(a,"out")) { s_out = argv[i++]; } else { fprintf(stderr,"Unknown switch '%s'\n",a); return 1; } } else { fprintf(stderr,"Unexpected arg '%s'\n",a); return 1; } } if (libmsfat_sanity_check() != 0) { fprintf(stderr,"libmsfat sanity check fail\n"); return 1; } if (s_image == NULL) { fprintf(stderr,"fatinfo --image <image> ...\n"); fprintf(stderr,"\n"); fprintf(stderr,"--partition <n> Hard disk image, use partition N from the MBR\n"); fprintf(stderr,"--cluster <n> Which cluster to start from (if not root dir)\n"); fprintf(stderr,"-o <file> Dump directory to file\n"); fprintf(stderr,"--nohex Don't hex dump to STDOUT\n"); return 1; } if (s_cluster != NULL) cluster = (libmsfat_cluster_t)strtoul(s_cluster,NULL,0); else cluster = 0; fd = open(s_image,O_RDONLY|O_BINARY); if (fd < 0) { fprintf(stderr,"Unable to open disk image, %s\n",strerror(errno)); return 1; } { /* make sure it's a file, or a block device */ _polyfill_struct_stat st; if (_polyfill_fstat(fd,&st) || (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))) { fprintf(stderr,"Image is not a file\n"); return 1; } } if (s_partition != NULL) { struct libpartmbr_context_t *ctx = NULL; int index = atoi(s_partition); int dfd = -1; if (index < 0) { fprintf(stderr,"Invalid index\n"); return 1; } ctx = libpartmbr_context_create(); if (ctx == NULL) { fprintf(stderr,"Cannot allocate libpartmbr context\n"); return 1; } /* good! hand it off to the context. use dup() because it takes ownership */ dfd = dup(fd); if (libpartmbr_context_assign_fd(ctx,dfd)) { fprintf(stderr,"libpartmbr did not accept file descriptor %d\n",fd); close(dfd); // dispose of it return 1; } dfd = -1; ctx->geometry.cylinders = 16384; ctx->geometry.sectors = 63; ctx->geometry.heads = 255; /* load the partition table! */ if (libpartmbr_context_read_partition_table(ctx)) { fprintf(stderr,"Failed to read partition table\n"); return 1; } /* index */ if ((size_t)index >= ctx->list_count) { fprintf(stderr,"Index too large\n"); return 1; } /* valid? */ struct libpartmbr_context_entry_t *ent = &ctx->list[(size_t)index]; if (ent->is_empty) { fprintf(stderr,"You chose an empty MBR partition\n"); return 1; } /* show */ printf("Chosen partition:\n"); printf(" Type: 0x%02x %s\n", (unsigned int)ent->entry.partition_type, libpartmbr_partition_type_to_str(ent->entry.partition_type)); if (!(ent->entry.partition_type == LIBPARTMBR_TYPE_FAT12_32MB || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16_32MB || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16B_8GB || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT32_CHS || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT32_LBA || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16B_LBA || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT12_32MB_HIDDEN || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16_32MB_HIDDEN || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16B_8GB_HIDDEN || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT32_CHS_HIDDEN || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT32_LBA_HIDDEN || ent->entry.partition_type == LIBPARTMBR_TYPE_FAT16B_LBA_HIDDEN)) { fprintf(stderr,"MBR type does not suggest a FAT filesystem\n"); return 1; } first_lba = ent->entry.first_lba_sector; size_lba = ent->entry.number_lba_sectors; /* done */ ctx = libpartmbr_context_destroy(ctx); } else { lseek_off_t x; first_lba = 0; x = _polyfill_lseek(fd,0,SEEK_END); if (x < (lseek_off_t)0) x = 0; x /= (lseek_off_t)512UL; if (x > (lseek_off_t)0xFFFFFFFFUL) x = (lseek_off_t)0xFFFFFFFFUL; size_lba = (uint32_t)x; _polyfill_lseek(fd,0,SEEK_SET); } printf("Reading from disk sectors %lu-%lu (%lu sectors)\n", (unsigned long)first_lba, (unsigned long)first_lba+(unsigned long)size_lba-(unsigned long)1UL, (unsigned long)size_lba); { lseek_off_t x = (lseek_off_t)first_lba * (lseek_off_t)512UL; if (_polyfill_lseek(fd,x,SEEK_SET) != x || read(fd,sectorbuf,512) != 512) { fprintf(stderr,"Unable to read boot sector\n"); return 1; } } { const char *err_str = NULL; if (!libmsfat_boot_sector_is_valid(sectorbuf,&err_str)) { printf("Boot sector is not valid: reason=%s\n",err_str); return 1; } } { struct libmsfat_bootsector *p_bs = (struct libmsfat_bootsector*)sectorbuf; int dfd; if (libmsfat_bs_compute_disk_locations(&locinfo,p_bs)) { printf("Unable to locate disk locations.\n"); return 1; } printf("Disk location and FAT info:\n"); printf(" FAT format: FAT%u\n", locinfo.FAT_size); printf(" FAT tables: %u\n", locinfo.FAT_tables); printf(" FAT table size: %lu sectors\n", (unsigned long)locinfo.FAT_table_size); printf(" FAT offset: %lu sectors\n", (unsigned long)locinfo.FAT_offset); printf(" Root directory: %lu sectors\n", (unsigned long)locinfo.RootDirectory_offset); printf(" Root dir size: %lu sectors\n", (unsigned long)locinfo.RootDirectory_size); printf(" Data offset: %lu sectors\n", (unsigned long)locinfo.Data_offset); printf(" Data size: %lu sectors\n", (unsigned long)locinfo.Data_size); printf(" Sectors/cluster: %u\n", (unsigned int)locinfo.Sectors_Per_Cluster); printf(" Bytes per sector: %u\n", (unsigned int)locinfo.BytesPerSector); printf(" Total clusters: %lu\n", (unsigned long)locinfo.Total_clusters); printf(" Total data clusts: %lu\n", (unsigned long)locinfo.Total_data_clusters); printf(" Max clusters psbl: %lu\n", (unsigned long)locinfo.Max_possible_clusters); printf(" Max data clus psbl:%lu\n", (unsigned long)locinfo.Max_possible_data_clusters); printf(" Total sectors: %lu sectors\n", (unsigned long)locinfo.TotalSectors); if (locinfo.FAT_size >= 32) { printf(" FAT32 FSInfo: %lu sector\n", (unsigned long)locinfo.fat32.BPB_FSInfo); printf(" Root dir cluster: %lu\n", (unsigned long)locinfo.fat32.RootDirectory_cluster); } msfatctx = libmsfat_context_create(); if (msfatctx == NULL) { fprintf(stderr,"Failed to create msfat context\n"); return -1; } dfd = dup(fd); if (libmsfat_context_assign_fd(msfatctx,dfd)) { fprintf(stderr,"Failed to assign file descriptor to msfat\n"); close(dfd); return -1; } dfd = -1; /* takes ownership, drop it */ msfatctx->partition_byte_offset = (uint64_t)first_lba * (uint64_t)512UL; if (libmsfat_context_set_fat_info(msfatctx,&locinfo)) { fprintf(stderr,"msfat library rejected disk location info\n"); return -1; } } /* FAT32 always starts from a cluster. * FAT12/FAT16 have a dedicated area for the root directory */ if (locinfo.FAT_size == 32) { if (s_cluster == NULL) cluster = locinfo.fat32.RootDirectory_cluster; } if (cluster >= locinfo.Max_possible_clusters) fprintf(stderr,"WARNING: cluster %lu >= max possible clusters %lu\n", (unsigned long)cluster, (unsigned long)locinfo.Max_possible_clusters); else if (cluster >= locinfo.Total_clusters) fprintf(stderr,"WARNING: cluster %lu >= total clusters %lu\n", (unsigned long)cluster, (unsigned long)locinfo.Total_clusters); else if ((s_cluster != NULL || cluster != (libmsfat_cluster_t)0UL) && cluster < (libmsfat_cluster_t)2UL) fprintf(stderr,"WARNING: cluster %lu is known not to have corresponding data storage on disk\n", (unsigned long)cluster); if (s_cluster != NULL || cluster != (libmsfat_cluster_t)0UL) printf("Reading directory starting from cluster %lu\n", (unsigned long)cluster); else printf("Reading directory from FAT12/FAT16 root directory area\n"); if (s_out != NULL) { out_fd = open(s_out,O_CREAT|O_TRUNC|O_BINARY|O_WRONLY,0644); if (out_fd < 0) { fprintf(stderr,"Failed to create dump file\n"); return 1; } } /* sanity check */ if (locinfo.FAT_size >= 32 && cluster < (libmsfat_cluster_t)2UL) { fprintf(stderr,"ERROR: FAT32 requires a root directory cluster to start from. There is no\n"); fprintf(stderr," dedicated root directory area like what FAT12/FAT16 has.\n"); return 1; } else if (locinfo.FAT_size < 32 && (locinfo.RootDirectory_offset == (uint32_t)0UL || locinfo.RootDirectory_size == (uint32_t)0UL)) { fprintf(stderr,"ERROR: FAT12/FAT16 root directory area does not exist\n"); return 1; } libmsfat_lfn_assembly_init(&lfn_name); if (cluster >= (libmsfat_cluster_t)2UL) { libmsfat_cluster_t next_cluster; uint32_t rd,cnt,scan; uint64_t offset; uint64_t sector; uint32_t clsz; uint8_t col; clsz = libmsfat_context_get_cluster_size(msfatctx); if (clsz == (uint32_t)0) { fprintf(stderr,"Unable to get cluster size\n"); return 1; } printf(" Cluster size: %lu bytes\n", (unsigned long)clsz); printf("\n"); do { if (libmsfat_context_get_cluster_sector(msfatctx,§or,cluster)) { fprintf(stderr,"Failed to map sector from cluster number %lu\n",(unsigned long)cluster); return 1; } if (libmsfat_context_get_cluster_offset(msfatctx,&offset,cluster)) { fprintf(stderr,"Failed to map offset from cluster number %lu\n",(unsigned long)cluster); return 1; } if (libmsfat_context_read_FAT(msfatctx,&next_cluster,cluster,0)) { fprintf(stderr,"WARNING: unable to read FAT entry for cluster #%lu\n",(unsigned long)cluster); next_cluster = libmsfat_FAT32_CLUSTER_MASK; } if (msfatctx->fatinfo.FAT_size == 32) next_cluster &= libmsfat_FAT32_CLUSTER_MASK; printf(" Cluster: #%lu starts at sector %llu (%llu bytes)", (unsigned long)cluster, (unsigned long long)sector, (unsigned long long)offset); if (!libmsfat_context_fat_is_end_of_chain(msfatctx,next_cluster)) printf(" -> next cluster is %lu",(unsigned long)next_cluster); printf("\n"); col = 0; cnt = 0; rd = clsz; while (rd != 0) { uint32_t rdsz; rdsz = rd; if (rdsz > (uint32_t)sizeof(sectorbuf)) rdsz = (uint32_t)sizeof(sectorbuf); if (libmsfat_context_read_disk(msfatctx,sectorbuf,offset,rdsz)) { fprintf(stderr,"Failed to read from disk offset %llu\n",(unsigned long long)offset); break; } if (out_fd >= 0) { if (write(out_fd,sectorbuf,(size_t)rdsz) != (int)rdsz) { fprintf(stderr,"Failed to write to dump file\n"); break; } } if (!nohex) { for (scan=0; scan < rdsz; scan++) { if (col == 0) printf(" 0x%08lx: ",(unsigned long)cnt); printf("%02x ",sectorbuf[scan]); cnt++; if ((++col) >= 32) { printf("\n"); if ((unsigned int)scan >= (unsigned int)31) { unsigned char *p = sectorbuf + scan - 31; assert((scan % 32) == 31); print_dirent(msfatctx,(struct libmsfat_dirent_t*)p,nohex); dirent_assemble_lfn(msfatctx,(struct libmsfat_dirent_t*)p); } col = 0; } } } else { for (scan=0; scan < rdsz; scan++) { cnt++; if ((++col) >= 32) { if ((unsigned int)scan >= (unsigned int)31) { unsigned char *p = sectorbuf + scan - 31; assert((scan % 32) == 31); print_dirent(msfatctx,(struct libmsfat_dirent_t*)p,nohex); dirent_assemble_lfn(msfatctx,(struct libmsfat_dirent_t*)p); } col = 0; } } } offset += (uint64_t)rdsz; rd -= rdsz; } if (col != 0 && !nohex) printf("\n"); if (next_cluster == (libmsfat_cluster_t)1UL) { fprintf(stderr,"Next cluster is not a valid data cluster. Stopping now.\n"); break; } else if (next_cluster == cluster) { fprintf(stderr,"Next cluster is the same as the current cluster. Stopping now.\n"); break; } else if (libmsfat_context_fat_is_end_of_chain(msfatctx,next_cluster)) { break; } cluster = next_cluster; } while (1); } else { uint32_t rd,cnt,scan; uint64_t offset; uint64_t sector; uint32_t clsz; uint8_t col; sector = (uint64_t)msfatctx->fatinfo.RootDirectory_offset; offset = (uint64_t)sector * msfatctx->fatinfo.BytesPerSector; offset += (uint64_t)msfatctx->partition_byte_offset; printf(" Root directory starts at sector %llu (%llu bytes)\n", (unsigned long long)sector, (unsigned long long)offset); clsz = (uint32_t)msfatctx->fatinfo.BytesPerSector * (uint32_t)msfatctx->fatinfo.RootDirectory_size;; if (clsz == (uint32_t)0) { fprintf(stderr,"Unable to get cluster size\n"); return 1; } printf(" Root dir size: %lu bytes\n", (unsigned long)clsz); printf("\n"); col = 0; cnt = 0; rd = clsz; while (rd != 0) { uint32_t rdsz; rdsz = rd; if (rdsz > (uint32_t)sizeof(sectorbuf)) rdsz = (uint32_t)sizeof(sectorbuf); if (libmsfat_context_read_disk(msfatctx,sectorbuf,offset,rdsz)) { fprintf(stderr,"Failed to read from disk offset %llu\n",(unsigned long long)offset); break; } if (out_fd >= 0) { if (write(out_fd,sectorbuf,(size_t)rdsz) != (int)rdsz) { fprintf(stderr,"Failed to write to dump file\n"); break; } } if (!nohex) { for (scan=0; scan < rdsz; scan++) { if (col == 0) printf(" 0x%08lx: ",(unsigned long)cnt); printf("%02x ",sectorbuf[scan]); cnt++; if ((++col) >= 32) { printf("\n"); if ((unsigned int)scan >= (unsigned int)31) { unsigned char *p = sectorbuf + scan - 31; assert((scan % 32) == 31); print_dirent(msfatctx,(struct libmsfat_dirent_t*)p,nohex); dirent_assemble_lfn(msfatctx,(struct libmsfat_dirent_t*)p); } col = 0; } } } else { for (scan=0; scan < rdsz; scan++) { cnt++; if ((++col) >= 32) { if ((unsigned int)scan >= (unsigned int)31) { unsigned char *p = sectorbuf + scan - 31; assert((scan % 32) == 31); print_dirent(msfatctx,(struct libmsfat_dirent_t*)p,nohex); dirent_assemble_lfn(msfatctx,(struct libmsfat_dirent_t*)p); } col = 0; } } } offset += (uint64_t)rdsz; rd -= rdsz; } if (col != 0 && !nohex) printf("\n"); } if (out_fd >= 0) close(out_fd); out_fd = -1; msfatctx = libmsfat_context_destroy(msfatctx); close(fd); fd = -1; return 0; }
int ext2(void) { printf("Hello World, this is the Ext2 FS\n"); // Hardcode test fs into memory so that we can test read // Set up the superblock struct ext2_super_block *sb; sb = (struct ext2_super_block*) (VIRT_MEM_LOCATION + EXT2_SUPERBLOCK_LOCATION); sb->s_inodes_count = 50; sb->s_blocks_count = 8192; sb->s_r_blocks_count = 6; sb->s_free_blocks_count = 8186; sb->s_free_inodes_count = 49; sb->s_first_data_block = 1; sb->s_log_block_size = 0; sb->s_log_frag_size = 0; sb->s_blocks_per_group = 8192; sb->s_frags_per_group = 8192; sb->s_inodes_per_group = 50; sb->s_magic = EXT2_MAGIC; sb->s_state = EXT2_VALID_FS; sb->s_errors = EXT2_ERRORS_CONTINUE; sb->s_creator_os = EXT2_OS_XINU; sb->s_first_ino = 2; sb->s_inode_size = sizeof( struct ext2_inode ); sb->s_block_group_nr = 0; char name[16] = "FAKE RAM FS :D"; memcpy(sb->s_volume_name,name,16); // Set up the group descriptors table struct ext2_group_desc *gpd; // DUMB POINTER ARITHMATIC gpd = (struct ext2_group_desc *) (sb + 1); gpd->bg_block_bitmap = 2; gpd->bg_inode_bitmap = 3; gpd->bg_inode_table = 4; gpd->bg_free_blocks_count = 44; gpd->bg_free_inodes_count = 19; gpd->bg_used_dirs_count = 1; // Set up the block bitmap uint8 *blBitmap; blBitmap = (uint8 *) (sb + 2); blBitmap[0] = 0x3F; // super block int i; for (i = 6; i < sb->s_blocks_count; i++) blBitmap[i] = 0; // Set up the inode bitmap uint8 *iBitmap; iBitmap = (uint8 *) (sb + 3); iBitmap[0] = 0x1; // . for (i = 1; i < sb->s_inodes_count; i++) iBitmap[i] = 0; // Set up the inode table struct ext2_inode *iTbl; iTbl = (struct ext2_inode *) (sb + 4); // Set up . inode iTbl->i_mode = EXT2_S_IFDIR; iTbl->i_size = sizeof(struct ext2_dir_entry_2); iTbl->i_links_count = 0; iTbl->i_blocks = 1; iTbl->i_flags = EXT2_NODUMP_FL; iTbl->i_block[0] = 5; // Set up . entry for the home directory struct ext2_dir_entry_2 *blk5; blk5 = (struct ext2_dir_entry_2 *) (sb + 5); blk5->inode = 1; blk5->next_dirent = 0; blk5->name_len = 1; blk5->filetype = 2; char homeName[255] = "."; memcpy(blk5->name, homeName, 255); _fs_ext2_init(); touch1( xinu_fs, "./", "test" ); char bufferL[9] = "Go long!"; uint32 bytes_written; ext2_write_status stat = ext2_write_file_by_path( xinu_fs, "./test", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "yo"); stat = ext2_write_file_by_path( xinu_fs, "./yo", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "whoah" ); stat = ext2_write_file_by_path( xinu_fs, "./whoah", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "iasjdf" ); stat = ext2_write_file_by_path( xinu_fs, "./iasjdf", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "f" ); stat = ext2_write_file_by_path( xinu_fs, "./f", bufferL, &bytes_written, 0, 8 ); ls1( xinu_fs, "./" ); printf("removing yo\n"); rm1( xinu_fs, "./", "yo" ); ls1( xinu_fs, "./" ); printf("touching asdf\n"); touch1( xinu_fs, "./", "asdf" ); stat = ext2_write_file_by_path( xinu_fs, "./asdf", bufferL, &bytes_written, 0, 8 ); ls1( xinu_fs, "./" ); printf("mking dir\n"); mkdir1( xinu_fs, "./", "dir" ); ls1( xinu_fs, "./" ); printf("touching yo\n"); touch1( xinu_fs, "./dir/", "yo" ); ls1( xinu_fs, "./dir/"); copy1( xinu_fs, "./", "whoah", "./", "hello" ); ls1( xinu_fs, "./" ); cat1( xinu_fs, "./", "hello" ); copy1( xinu_fs, "./", "hello", "./dir/", "hello" ); printf("HERE\n"); ls1( xinu_fs, "./dir/" ); cat1( xinu_fs, "./dir/", "hello" ); printf("removeing\n"); mv1( xinu_fs, "./dir/", "yo", "./", "a" ); ls1( xinu_fs, "./" ); cat1( xinu_fs, "./", "a" ); #if 0 // Test the read/write functions printf("Testing hardcoded data\n"); print_superblock( xinu_fs->sb ); struct ext2_inode *i1 = ext2_get_inode(xinu_fs, 1); print_inode( i1, 1, xinu_fs ); struct ext2_dir_entry_2 *home = ext2_get_first_dirent(xinu_fs, i1 ); print_dirent( home ); uint32 inode_num = ext2_inode_alloc( xinu_fs ); struct ext2_inode *i2 = ext2_get_inode( xinu_fs, inode_num+1 ); i2->i_mode = EXT2_S_IFREG; i2->i_size = 0; printf("Allocated new inode\n"); print_inode( i2, inode_num+1, xinu_fs ); struct ext2_dir_entry_2 *dirent = ext2_dirent_alloc( xinu_fs, i1 ); dirent->inode = 2; dirent->next_dirent = 0; dirent->name_len = 4; dirent->filetype = EXT2_FT_REG_FILE; char testName[255] = "test"; memcpy(dirent->name, testName, 255); printf("Allocated new dir_entry_2 test\n"); print_dirent( dirent ); char path[8] = "./test"; char buffer[14] = "Writing! Yay!"; char bufferL[9] = "Go long!"; uint32 bytes_written; ext2_write_status stat = ext2_write_file_by_path( xinu_fs, path, buffer, &bytes_written, 0, 13 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); char buffer2[12*1024]; // stat = ext2_write_file_by_path( xinu_fs, path, buffer2, // &bytes_written, 13, (12*1024)-1 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); // stat = ext2_write_file_by_path( xinu_fs, path, bufferL, // &bytes_written, (12*1024)+12, 8 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); int read = 0; char readBuf[30]; read = ext2_read_dirent( xinu_fs, dirent, readBuf, 0, 29); printf("Read %d bytes readBuf = %s\n", read, readBuf); // read = ext2_read_dirent( xinu_fs, dirent, readBuf, (12*1024)+12, 10); // printf("Read %d bytes readBuf = %s\n", read, readBuf); #endif return 0; }