view src/testFS.c @ 46:a6be89bc4b04

Moved fs.c to testFS.c
author Jonathan Pevarnek <pevarnj@gmail.com>
date Fri, 08 Apr 2011 10:31:03 -0400
parents src/fs.c@9cec88f4c98b
children eda059d74100
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)
{
	init_io_int();
	init_console();
	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;
		if(fileLoc == nFiles) continue;

		Inode fileToRead;
		if(readFSBlock(dev, fileLoc, &fileToRead)) {
			sPrint("ERROR\n");
			goto END;
		}

		u32 fileSize = fileToRead.size;

		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(;;) {
		sGet(buffer, 0);
	}
}