📄 scan.c
字号:
/*************************************************************
File Name: SCAN.C *
**************************************************************
Programmer: MSC
Last Modified Date: 2000/10/30
Compiler : GNU Cross-compiler/SDS
Platform : X86 protection mode, MIPS, Dragonball
Usage :
RD_scanDisk functions for RAMDisk 4.0
See scan.h for usage.
*************************************************************/
#include <kernel/linklist.h>
#include <sys/syscall.h>
#include <kernel/malloc.h>
//#include <ansi_c/stdio.h>
#include <stdio.h>
#include <ramdisk.h>
#include <piece.h>
#include <dskblk.h>
//#include "myansi.h"
#include <scan.h>
#ifdef RAMDISK_ID
/*
#if (MM_TYPE == MM_SUPER_BMP)
#define CHUNK_SIZE 32
#endif
*/
/* the list of sub-dirs to be processed */
struct dLinkList DirList;
int FileErrCount;
/* basic.c */
extern int InitRD;
//extern int RDerrno;
extern void *RD_BootBegin;
extern unsigned long RD_DiskSize;
extern unsigned long RD_SignSize;
extern unsigned char *RAMMemory;
extern int RD_SemaphoreID;
extern int RDOutput;
/* piece.c */
// added by chilong 01/28/2002
extern void **RD_PLT;
extern unsigned long RDPieceSize;
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
#else
extern unsigned long RDSystemBlockSize;
#endif
/* dskblk.c */
extern struct diskBlock *RD_FirstFreeBlock;
/*************************************************************
Fuction : RD_scanDisk
Scan the RAMDisk for errors
Input:
interactive - ECHO_ON: show progress during scanning
ECHO_OFF: show nothing during scanning
fix - 1: automatically fix error
0: report only, don't fix
Output:
0: no error is found
-1: system error (check RDerrno)
Otherwise:
bit 0: File/Dir error
bit 1: Disk space inconsistent
**************************************************************/
char RD_scanDisk(char interactive, char fix)
{
long totalUsedSize = 0;
long totalFileSize = 0;
long totalCompressSize = 0;
char returnValue;
if (InitRD == FALSE)
{
RDerrno = ERROR_FILE_SYSTEM_NOT_INIT;
return (char)-1;
}
RDerrno = 0;
sc_waitSemaphore(RD_SemaphoreID);
returnValue = RD_scanDisk_r(interactive, fix, &totalUsedSize, &totalFileSize, &totalCompressSize);
sc_signalSemaphore(RD_SemaphoreID);
return returnValue;
}
char RD_scanDisk_r(char interactive, char fix, long *totalUsedSize, long *totalFileSize, long *totalCompressSize)
{
long status;
char returnValue = 0;
char options = 0;
struct diskBlock *curBlock;
struct scanDir *curDir;
long totalSize = 0;
char *strTemp;
// added by chilong 01/28/2002
PIECE_DS *pPieceDS;
strTemp = NULL;
if (interactive == ECHO_ON)
{
strTemp = (char *)ap_malloc(256);
if (strTemp == NULL)
{
RDerrno = ERROR_ALLOC_MEM;
return (char)-1;
}
sprintf(strTemp, "Checking files & directories...");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
// initialize the double linked list of sub-directories
initDLinkList(&DirList);
// initialize the error counts of FATs
FileErrCount = 0;
if (interactive == ECHO_ON)
options |= INTERACTIVE;
if (fix == 1)
options |= AUTOFIX;
// size of disk information
#if (MM_TYPE == MM_SUPER_BMP)
// totalSize = ((RDPieceSize + (RD_PLT_ENTRY_NUM * sizeof(void *)) + HEADER - 1) / SUPER_BMP_CHUNK_SIZE + 1) * SUPER_BMP_CHUNK_SIZE;
/**** modified by chilong 10/4/2001 ****/
totalSize = ((RDPieceSize + (RD_PLT_ENTRY_NUM * sizeof(PIECE_DS)) + HEADER - 1) / SUPER_BMP_CHUNK_SIZE + 1) * SUPER_BMP_CHUNK_SIZE;
/**** modified by chilong 10/4/2001 ****/
totalSize += (RD_SignSize - HEADER);
totalSize -= RDPieceSize;
#else
totalSize = RDPieceSize + (RD_PLT_ENTRY_NUM * sizeof(void *)) + RD_SignSize;
#endif
curBlock = (struct diskBlock *)(((struct signature *)RD_BootBegin)->rootBegin);
if (RD_checkBlockLocation(curBlock) == -1)
{
RDerrno = ERROR_FILE_SYSTEM;
ap_free(strTemp);
return (char)-1;
}
// insert the root dir to the dir list
if ((curDir = (struct scanDir *)ap_malloc(sizeof(struct scanDir))) == NULL)
{
RDerrno = ERROR_ALLOC_MEM;
ap_free(strTemp);
return (char)-1;
}
memoryZero((void *)curDir, (unsigned int)sizeof(struct scanDir));
curDir->pathName[0] = '\0'; // the root dir
curDir->startBlock = curBlock;
curDir->theEntry = NULL;
if (insertTo(&DirList, (void *)curDir) == FAIL)
{
RDerrno = ERROR_OPERATING_SYSTEM_ERROR;
ap_free(curDir);
ap_free(strTemp);
return (char)-1;
}
while (DirList.back != NULL)
{
curDir = DirList.back->elementPointer;
removeFrom(DirList.back);
status = RD_checkDir(options, curDir, totalFileSize, totalCompressSize, strTemp);
if (status == -1)
{
ap_free(curDir);
ap_free(strTemp);
freeDLinkList(&DirList);
return (char)-1;
}
totalSize += status;
ap_free(curDir);
}
if (FileErrCount != 0)
{
if (interactive == ECHO_ON)
{
sprintf(strTemp, "Number of file/dir errors: %d", FileErrCount);
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
returnValue |= ERR_FILEDIR;
}
else
{
if (interactive == ECHO_ON)
{
sprintf(strTemp, "There is no file/dir error.");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
}
*totalUsedSize = totalSize;
// check if there are unchained clusters in FATs
if (interactive == ECHO_ON)
{
sprintf(strTemp, "Checking free RAMDisk space...");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
curBlock = RD_FirstFreeBlock;
while (curBlock != NULL)
{
if (RD_checkBlockLocation(curBlock) == -1)
{
if (interactive == ECHO_ON)
{
sprintf(strTemp, "Free block out of bound!");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
returnValue |= ERR_SPACE;
break;
}
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
totalSize += (B_HEADER + curBlock->size + B_TAIL);
#else
totalSize += RDSystemBlockSize;
#endif
curBlock = (struct diskBlock *)curBlock->nextBlock;
}
if (totalSize != RD_DiskSize)
{
if (interactive == ECHO_ON)
{
sprintf(strTemp, "Disk size unmatches!");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
sprintf(strTemp, "Disk size = %d", RD_DiskSize);
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
sprintf(strTemp, "Occupied size = %d", totalSize);
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
returnValue |= ERR_SPACE;
}
else
{
if (interactive == ECHO_ON)
{
sprintf(strTemp, "Disk space is consistent.");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
}
/**** added by chilong 01/28/2002 ****/
curBlock = RD_FirstFreeBlock;
while(curBlock != NULL)
{
// we use "option" to keep track of whether or not
// we need to move curBlock to the next later.
if (RD_checkBlockLocation(curBlock) == -1)
break;
options = 1;
for (status = 0; status < RD_PLT_ENTRY_NUM; status++)
{
pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + status);
// if (pPieceDS->startAddress != NULL)
// modified by chilong 02/07/2002
if (pPieceDS->startAddress != NULL && (unsigned long)pPieceDS->startAddress % 4 == 0)
{
// !!NOTE:
// about (pPieceDS->size - B_HEADER - B_TAIL),
// please refer to getPiece() & addNewPieceToFBL() in piece.c
if (curBlock == pPieceDS->startAddress &&
curBlock->size == (pPieceDS->size - B_HEADER - B_TAIL) )
{
// we move curBlock to the next block first
// because curBlock will be freed and
// set to NULL after invoking freePiece()
curBlock = curBlock->nextBlock;
freePiece((void*)pPieceDS->startAddress);
options = 0;
break;
}
}
}
if (options)
curBlock = curBlock->nextBlock;
}
/**** added by chilong 01/28/2002 ****/
if (interactive == ECHO_ON)
{
sprintf(strTemp, "File system integrity checking done.");
/*
if (RDOutput == TO_SERIAL_PORT)
SprintStringLn(strTemp);
else
printStringLn(strTemp);
*/
RD_showMessage(strTemp);
}
ap_free(strTemp);
return returnValue;
}
/*************************************************************
Fuction : RD_checkFile
Check the integrity of a file entry
Input:
options - interactive? auto-fix?
pathname - the pathname of the file
entry - the directory structure of the target file
strTemp - a string buffer
Output:
totalFileSize - the total size of the files
totalCompressSize - the total compressed size of the files
Return value:
-1 : file has error
else : actual memory size taken by the file
**************************************************************/
long RD_checkFile(char options, unsigned char *pathname, struct directory *entry, long *totalFileSize, long *totalCompressSize, char *strTemp)
{
struct diskBlock *curBlock;
struct diskBlock *prevBlock = NULL;
long totalSize = 0;
long fileSize = 0;
long compressSize = 0;
/**** added by chilong 9/26/2001 ****/
struct diskBlock *tmpBlock;
int bBlockErr = 0; // 0: no error
// 1: block address error
// 2: block data error
/**** added by chilong 9/26/2001 ****/
if ((unsigned char)(entry->name[0]) == DELETED_ENTRY)
{
// skip deleted entry
return 0;
}
/*
// print filename
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -