Mercurial > sos > sos
view src/fs.c @ 37:b2bb007e5789
The filesytem stuff actually does something now
The code is still messy but for now, I shall focus on laundry (and after that, sleep)
Once the user enters the filename, this now dumps the entire contents of the
file to the screen. It would be nice to have this wait for the user to push
enter or something, not sure how possible that is though...
author | Jonathan Pevarnek <pevarnj@gmail.com> |
---|---|
date | Fri, 08 Apr 2011 00:22:44 -0400 |
parents | 3acc1f944c7b |
children | 4f8e3bb19646 |
line wrap: on
line source
#include <std.h> struct SUPERBLOCK { u32 magic; // == 0x42420374 u32 root_inode; // the disk block containing the root inode u32 nblocks; // number of block on the disk u32 _pad[253]; // unused (should be '\0' filled) }; typedef struct SUPERBLOCK Superblock; struct INODE { u32 size; // file length in bytes u32 _pad0; // unused (should be 0) u64 ctime; // creation time stamp u64 mtime; // last modification time stamp u16 nblocks; // number of data blocks in this file u16 _pad1; // unused (should be 0) u32 _pad2; // unused (should be 0) u32 blocks[248]; // file block ptrs }; typedef struct INODE Inode; struct DIRENTRY { //32 bytes char fname[28]; u32 inode; }; typedef struct DIRENTRY Direntry; //REQUIRES: fsBlock points to an object with size at least 1024 //EFFECTS: Sets fsBlock to be equal int readFSBlock(u32 dev, u32 blkno, void *fsBlock) { if(fba_read_blk(dev, blkno*2, fsBlock)) return 1; if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1; return 0; } void printFname(char *name) { putline(name, 28); } //Sets name to contain a filename entered by the user //REQUIRES: name is 28 characters long void getFname(char *fname) { int chars = getline(fname, 28); for(;chars < 28; chars++) { fname[chars] = ' '; } } //Checks whether two file names are equal int fnameCmp(const char *a, const char *b) { int i; for(i = 0; i < 28; i++, a++, b++) { if(*a - *b) return *a - *b; } return 0; } //Finds the item within an array of filenames with the same name as fname int fnameLookup(char *fname, const Direntry array[], int last) { int i; for(i = 0; i < last; i++) if(!fnameCmp(fname, array[i].fname)) return i; return last; } void dumpText(char *text, int size) { do { putline(text, (size > CON_LEN)?CON_LEN:size); size -= CON_LEN; text += CON_LEN; } while(size > 0); } void start(u64 __memsize) { sPrint(""); //I have no idea why I would possibly need this... char buffer[256]; int i; u32 dev = find_dev(0x100); Superblock sb; if(readFSBlock(dev, 1, &sb)) { //get the super block sPrint("ERROR\n"); goto END; } Inode root; if(readFSBlock(dev, sb.root_inode, &root)) { //get the root inode sPrint("ERROR\n"); goto END; } int nFiles = root.size/sizeof(Direntry); //calculate how many files (assume less than 32 for the moment) //TODO get rid of assumption Direntry direntries[32]; if(readFSBlock(dev, root.blocks[0], direntries)) { //get the "first 32" files sPrint("ERROR\n"); goto END; } while(1) { //Prints off the name of each file Direntry *dp; for(dp = direntries; dp - direntries < nFiles; dp++) { printFname(dp->fname), sPrint("\n"); } char fname[28]; sPrint("Please enter the file to read: "); getFname(fname); int file = fnameLookup(fname, direntries, nFiles); u32 fileLoc = direntries[file].inode; Inode fileToRead; if(readFSBlock(dev, fileLoc, &fileToRead)) { sPrint("ERROR\n"); goto END; } u32 fileSize = fileToRead.size; const u32 origFileSize = fileSize; for(i = 0; i < fileToRead.nblocks; i++) { char text[1024]; if(readFSBlock(dev, fileToRead.blocks[i], text)) { sPrint("ERROR\n"); goto END; } dumpText(text, (fileSize > 1024)?1024:fileSize); fileSize -= 1024; } } END: sPrint("DONE\n"); for(;;) { char buffer[1]; sGet(buffer, 0); } }