void Print_AnrBlocks (void) { short blocks_cnt; /* just a counter */ unsigned long offset_in_idx_file; /* no comments */ long offs; long random_index; /* random-chosen block index */ short repeats_number; int max_index=Flags_Get_Blocks_Number (); int start_number = Flags_Get_Random_Choosing() ? 0 : Flags_Get_Start_Number(); repeats_number = Flags_Get_Repeats_Number (); for (blocks_cnt=0; blocks_cnt<repeats_number && start_number+blocks_cnt<max_index; blocks_cnt++) { random_index = Matrix_Numbers_Get(blocks_cnt); offset_in_idx_file = (random_index) << 2; Files_Get_Offset_From_Index (offset_in_idx_file, &offs, sizeof(offs)); Block_Read (offs); Block_Print (random_index); Print_FButtons (random_index); //Print_Voting (random_index); printf ("<hr>\n"); } }
/* * Read a full GOSFS block from disk * Return 0 on success, exits on error * Note: blocknum is the GOSFS block number */ int GOSFS_Block_Read(struct Block_Device *dev, int blockNum, void *buf) { int rc = 0; int index = 0; for (index = 0; index < DISK_BLOCKS_PER_GOSFS; index++) { rc = Block_Read(dev, blockNum * DISK_BLOCKS_PER_GOSFS + index, buf + (index * SECTOR_SIZE)); if (rc != 0) Exit(rc); } return rc; }
/* Reads in an entire GOSFSBlock (4KB) and copies into dest */ static int readGOSFSBlock(struct Block_Device *dev, int gosfsBlock, void *dest, size_t numBytes) { char buffer[GOSFS_BLOCK_SIZE], *bufferPtr = buffer; int blockIndex = gosfsBlock * (GOSFS_BLOCK_SIZE / SECTOR_SIZE); int i, rc; for (i = 0; i < (GOSFS_BLOCK_SIZE / SECTOR_SIZE); i++) { rc = Block_Read(dev, blockIndex + i, bufferPtr); if (rc < 0) goto fail; bufferPtr += SECTOR_SIZE; } memcpy(dest, buffer, numBytes); return 0; fail: return rc; }
/* * Mount function for PFAT filesystem. */ static int PFAT_Mount(struct Mount_Point *mountPoint) { struct PFAT_Instance *instance = 0; bootSector *fsinfo; void *bootSect = 0; int rootDirSize; int rc; int i; /* Allocate instance. */ instance = (struct PFAT_Instance*) Malloc(sizeof(*instance)); if (instance == 0) goto memfail; memset(instance, '\0', sizeof(*instance)); fsinfo = &instance->fsinfo; Debug("Created instance object\n"); /* * Allocate buffer to read bootsector, * which contains metainformation about the PFAT filesystem. */ bootSect = Malloc(SECTOR_SIZE); if (bootSect == 0) goto memfail; /* Read boot sector */ if ((rc = Block_Read(mountPoint->dev, 0, bootSect)) < 0) goto fail; Debug("Read boot sector\n"); /* Copy filesystem parameters from boot sector */ memcpy(&instance->fsinfo, ((char*)bootSect) + PFAT_BOOT_RECORD_OFFSET, sizeof(bootSector)); Debug("Copied boot record\n"); /* Does magic number match? */ if (fsinfo->magic != PFAT_MAGIC) { Print("Bad magic number (%x) for PFAT filesystem\n", fsinfo->magic); goto invalidfs; } Debug("Magic number is good!\n"); /* Do filesystem params look reasonable? */ if (fsinfo->fileAllocationOffset <= 0 || fsinfo->fileAllocationLength <= 0 || fsinfo->rootDirectoryCount < 0 || fsinfo->rootDirectoryOffset <= 0) { Print("Invalid parameters for PFAT filesystem\n"); goto invalidfs; } Debug("PFAT filesystem parameters appear to be good!\n"); /* Allocate in-memory FAT */ instance->fat = (int*) Malloc(fsinfo->fileAllocationLength * SECTOR_SIZE); if (instance->fat == 0) goto memfail; /* Read the FAT */ for (i = 0; i < fsinfo->fileAllocationLength; ++i) { int blockNum = fsinfo->fileAllocationOffset + i; char *p = ((char*)instance->fat) + (i * SECTOR_SIZE); if ((rc = Block_Read(mountPoint->dev, blockNum, p)) < 0) goto fail; } Debug("Read FAT successfully!\n"); /* Allocate root directory */ rootDirSize = Round_Up_To_Block(sizeof(directoryEntry) * fsinfo->rootDirectoryCount); instance->rootDir = (directoryEntry*) Malloc(rootDirSize); /* Read the root directory */ Debug("Root directory size = %d\n", rootDirSize); for (i = 0; i < rootDirSize; i += SECTOR_SIZE) { int blockNum = fsinfo->rootDirectoryOffset + i; if ((rc = Block_Read(mountPoint->dev, blockNum, instance->rootDir + (i*SECTOR_SIZE))) < 0) goto fail; } Debug("Read root directory successfully!\n"); /* Create the fake root directory entry. */ memset(&instance->rootDirEntry, '\0', sizeof(directoryEntry)); instance->rootDirEntry.readOnly = 1; instance->rootDirEntry.directory = 1; instance->rootDirEntry.fileSize = instance->fsinfo.rootDirectoryCount * sizeof(directoryEntry); /* Initialize instance lock and PFAT_File list. */ Mutex_Init(&instance->lock); Clear_PFAT_File_List(&instance->fileList); /* Attempt to register a paging file */ PFAT_Register_Paging_File(mountPoint, instance); /* * Success! * This mount point is now ready * to handle file accesses. */ mountPoint->ops = &s_pfatMountPointOps; mountPoint->fsData = instance; return 0; memfail: rc = ENOMEM; goto fail; invalidfs: rc = EINVALIDFS; goto fail; fail: if (instance != 0) { if (instance->fat != 0) Free(instance->fat); if (instance->rootDir != 0) Free(instance->rootDir); Free(instance); } if (bootSect != 0) Free(bootSect); return rc; }
/* * Read function for PFAT files. */ static int PFAT_Read(struct File *file, void *buf, ulong_t numBytes) { struct PFAT_File *pfatFile = (struct PFAT_File*) file->fsData; struct PFAT_Instance *instance = (struct PFAT_Instance*) file->mountPoint->fsData; ulong_t start = file->filePos; ulong_t end = file->filePos + numBytes; ulong_t startBlock, endBlock, curBlock; ulong_t i; /* Special case: can't handle reads longer than INT_MAX */ if (numBytes > INT_MAX) return EINVALID; /* Make sure request represents a valid range within the file */ if (start >= file->endPos || end > file->endPos || end < start) { Debug("Invalid read position: filePos=%lu, numBytes=%lu, endPos=%lu\n", file->filePos, numBytes, file->endPos); return EINVALID; } /* * Now the complicated part; ensure that all blocks containing the * data we need are in the file data cache. */ startBlock = (start % SECTOR_SIZE) / SECTOR_SIZE; endBlock = Round_Up_To_Block(end) / SECTOR_SIZE; /* * Traverse the FAT finding the blocks of the file. * As we encounter requested blocks that aren't in the * file data cache, we issue requests to read them. */ curBlock = pfatFile->entry->firstBlock; for (i = 0; i < endBlock; ++i) { /* Are we at a valid block? */ if (curBlock == FAT_ENTRY_FREE || curBlock == FAT_ENTRY_EOF) { Print("Unexpected end of file in FAT at file block %lu\n", i); return EIO; /* probable filesystem corruption */ } /* Do we need to read this block? */ if (i >= startBlock) { int rc = 0; /* Only allow one thread at a time to read this block. */ Mutex_Lock(&pfatFile->lock); if (!Is_Bit_Set(pfatFile->validBlockSet, i)) { /* Read block into the file data cache */ Debug("Reading file block %lu (device block %lu)\n", i, curBlock); rc = Block_Read(file->mountPoint->dev, curBlock, pfatFile->fileDataCache + i*SECTOR_SIZE); if (rc == 0) /* Mark as having read this block */ Set_Bit(pfatFile->validBlockSet, i); } /* Done attempting to fetch the block */ Mutex_Unlock(&pfatFile->lock); if (rc != 0) return rc; } /* Continue to next block */ ulong_t nextBlock = instance->fat[curBlock]; curBlock = nextBlock; } /* * All cached data we need is up to date, * so just copy it into the caller's buffer. */ memcpy(buf, pfatFile->fileDataCache + start, numBytes); Debug("Read satisfied!\n"); return numBytes; }
//write character string into newly created file //returns number of bytes written int Write_File(int inode_number, int offset, char* to_write, int bytes) { //make sure inode is valid file to read from Inode curNode = Inode_Read(inode_number); if ((curNode.Inode_Number == -1) || (curNode.Flag != 1)) { printf("Error, Inode is invalid\n"); return -1; } //inode is not a valid file/is not open //make sure we're adding onto the end of the file if (offset != curNode.File_Size) { printf("Error, writing to an invalid offset\n"); return -1; } //trying to write to an invalid offset //make sure we have enough space to write the string int endBlock = curNode.End_Block; if (endBlock == -1) { Super_block curSuper = Superblock_Read(); endBlock = curSuper.next_free_block; } int totalBytes = bytes; //total number of bytes if ((curNode.File_Size % 512) != 0) //look at existing block space { totalBytes += curNode.File_Size % 512; totalBytes -= 512; } endBlock += totalBytes / 512; //additional full blocks needed if ((totalBytes % 512) != 0) {endBlock++;} //overflow into next block if (endBlock > 8191) { printf("Error, not enough memory for file\n"); return -1; } //we don't have enough blocks //if this is a new file, set up inode with next free block int curBlock = curNode.End_Block; int bytesWritten = 0; totalBytes = bytes; Super_block curSuper = Superblock_Read(); if (curBlock == -1) { curBlock = curSuper.next_free_block++; Superblock_Write(curSuper); curNode.Start_Block = curBlock; Inode_Write(inode_number, curNode); } //fill up last file block if it is not full yet if ((curNode.File_Size % 512) != 0) { int curLength = curNode.File_Size % 512; int fillLength = 512 - curLength; if (bytes < fillLength) {fillLength = bytes;} int totalLength = curLength + fillLength; char curString[totalLength]; if (Block_Read(curBlock, curLength, curString) != curLength) { printf("Error, could not read block\n"); return -1; } //error filling up block if (concatString(curString, to_write, curLength, fillLength) != fillLength) { printf("Error, could not copy string portion\n"); return -1; } //error filling up block if (Block_Write(curBlock, totalLength, curString) != totalLength) { printf("Error, could not write to block\n"); return -1; } //error writing to block to_write += fillLength; bytesWritten += fillLength; curNode.File_Size += bytesWritten; if (bytesWritten != bytes) { curBlock = curSuper.next_free_block++; Superblock_Write(curSuper); } } int bytesLeft = bytes - bytesWritten; int totalBytesWritten = bytesWritten; while(bytesLeft) { bytesWritten = Block_Write(curBlock, (bytesLeft > 512 ? 512:bytesLeft), to_write); if(bytesWritten == 0) { printf("Error, could not write to block\n"); return -1; } bytesLeft -= bytesWritten; to_write += bytesWritten; totalBytesWritten += bytesWritten; curNode.File_Size += bytesWritten; if (bytesLeft) { curBlock = curSuper.next_free_block++; Superblock_Write(curSuper); } } curNode.End_Block = curBlock; Inode_Write(inode_number, curNode); return totalBytesWritten; }
//reads the specified bytes into a character array //returns the number of bytes read int Read_File(int inode_number, int offset, int count, char* to_read) { //check input values if ((offset < 0) || (count < 1)) { printf("Error, invalid offset/count\n"); return -1; } //invalid offset/count //make sure inode is valid file to read from Inode curNode = Inode_Read(inode_number); if ((curNode.Inode_Number == -1) || (curNode.Flag != 1)) { printf("Error, Inode invalid\n"); return -1; } //inode is not a valid file/is not open //check file size and number of bytes requested if(curNode.File_Size < (offset + count)) { printf("Error, end of file reached\n"); return -1; } //file smaller than number of bytes requested //get correct block to start reading from and offset within block int curBlock = curNode.Start_Block; //current block we're reading while (offset > 512) { curBlock++; offset -= 512; } //set up variables for reading int bytesLeft = count; int firstBytes = (512-offset); //bytes read from first block if (firstBytes > count) {firstBytes = count;} bytesLeft -= firstBytes; int fullBlocks = bytesLeft / 512; //number of full blocks read int finalBytes = bytesLeft % 512; //bytes read from final block char firstString[firstBytes]; //string read from first block char* blockList[fullBlocks]; //list of full blocks read char finalString[finalBytes]; //string read from final block char curBlockString[512]; //current block we're reading //read portion of first block with offset if (Block_Read(curBlock, 512, curBlockString) != 512) { printf("Error, could not read block\n"); return -1; } //error reading block int i; for (i=0; i<firstBytes; i++) { firstString[i] = curBlockString[i+offset]; } curBlock++; //read all required full blocks for (i=0; i<fullBlocks; i++) { blockList[i] = (char*)malloc(512); //allocate new string if (Block_Read(curBlock, 512, blockList[i]) != 512) { printf("Error, could not read block\n"); return -1; } //error reading block curBlock++; } //read portion of last block if (Block_Read(curBlock, finalBytes, finalString) != finalBytes) { printf("Error, could not read block\n"); return -1; } //error reading block //copy string from first block into to_read int numRead = 0; if (copyString(to_read, firstString, firstBytes) != firstBytes) { printf("Error, could not copy string\n"); return -1; } //error copying string numRead += firstBytes; to_read += firstBytes; //copy all required full blocks into to_read for (i=0; i<fullBlocks; i++) { if (copyString(to_read, blockList[i], 512) != 512) { printf("Error, could not copy string\n"); return numRead; } //error copying string free(blockList[i]); //free allocated memory numRead += 512; to_read += 512; } //copy portion of final block into to_read if necessary if (finalBytes > 0) { if (copyString(to_read, finalString, finalBytes) != finalBytes) { printf("Error, could not copy string\n"); return numRead; } //error copying string } return count; //everything was read correctly }
_Bool Flash_Read(uint8_t addr, uint32_t* dist) { if (addr < USED_SIZE / 4) { if (ReadRequed) { uint8_t i; uint32_t CRC = USED_SIZE; Block_Read(NEW_BLOCK_ADDR); for (i = 0; i < USED_SIZE / 4; i++) { CRC ^= Using_Values[i]; } if (CRC == FMC_Read(NEW_BLOCK_ADDR + USED_SIZE)) { *dist = FMC_Read(NEW_BLOCK_ADDR + addr * 4); /*if (*dist == 0xffff) { return FALSE; }*/ ReadRequed = FALSE; return TRUE; } else { FMC_Erase(NEW_BLOCK_ADDR); Flash_Init(); DPRINTF(("Area 1 error! \n")); } Block_Read(BAK_BLOCK_ADDR); for (i = 0; i < USED_SIZE / 4; i++) { CRC ^= Using_Values[i]; } if (CRC == FMC_Read(BAK_BLOCK_ADDR + USED_SIZE)) { Block_Clear(NEW_BLOCK_ADDR); for (i = 0; i < USED_SIZE / 4; i++) { FMC_Write(NEW_BLOCK_ADDR + i * 4, Using_Values[i]); } FMC_Write(NEW_BLOCK_ADDR + USED_SIZE, CRC); *dist = FMC_Read(BAK_BLOCK_ADDR + addr * 4); /*if (*dist == 0xffff) { return FALSE; }*/ ReadRequed = FALSE; return TRUE; } else { FMC_Erase(BAK_BLOCK_ADDR); Flash_Init(); DPRINTF(("Area 2 CRC error! \n")); } } else { *dist = Using_Values[addr]; return TRUE; } } else { DPRINTF(("Err: Addr: %d overrange!\n", addr)); } return FALSE; }