⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************
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 + -