📄 doschklib.c
字号:
pFd->pVolDesc->pDirDesc->readDir( pFd, &pChkDesc->chkDir, &localFd ) == OK; pChkDesc->chkDir.dd_cookie = ddCookie ) { /* * backup current position in directory, because * other routines use the same DIR structure */ ddCookie = pChkDesc->chkDir.dd_cookie; work1 = strlen( pCurPathPos ); strcpy( pCurPathPos, pChkDesc->chkDir.dd_dirent.d_name ); if( pFd->pVolDesc->chkVerbLevel >= (DOS_CHK_VERB_2 >> 8) ) { printf( "\r%s", pChkDesc->chkCurPath ); for( ; work1 >= strlen( pCurPathPos ); work1 -- ) printf( " " ); /* clear extra characters */ } DBG_MSG( 100, "%s : stCl %u, size %u attrib %p\n", pChkDesc->chkDir.dd_dirent.d_name, localFlHdl.startClust, localFlHdl.size, (u_int)localFlHdl.attrib,0,0,0,0 ); /* some statistics */ if( (localFlHdl.attrib & DOS_ATTR_DIRECTORY) == 0 ) pChkDesc->chkNFiles ++; else pChkDesc->chkNDirs ++; /* check name */ if( pFd->pVolDesc->pDirDesc->nameChk != NULL && pFd->pVolDesc->pDirDesc->nameChk( pFd->pVolDesc, (u_char *)pChkDesc->chkDir.dd_dirent.d_name) == ERROR) { if( dosChkEntryDel( &localFd, FALSE, (u_char *)CHK_BAD_NAME, CURRENT_PATH, 0,0,0,0 ) == CHK_ERROR ) { return CHK_ERROR; } continue; } /* check chain */ if( dosChkChainVerify( &localFd ) == CHK_ERROR ) return CHK_ERROR; if( localFlHdl.deleted ) { if( (localFlHdl.attrib & DOS_ATTR_DIRECTORY) == 0 ) pChkDesc->chkNFiles --; else pChkDesc->chkNDirs --; continue; } /* chain is OK. */ /* total files size */ pChkDesc->chkTotalFSize += localFlHdl.size; /* absolute max time */ if( pFd->pVolDesc->pDirDesc->dateGet( &localFd, &pChkDesc->stat ) == ERROR ) { return CHK_ERROR; } if( pChkDesc->chkMaxCreatTime < pChkDesc->stat.st_ctime ) pChkDesc->chkMaxCreatTime = pChkDesc->stat.st_ctime; if( pChkDesc->chkMaxModifTime < pChkDesc->stat.st_mtime ) pChkDesc->chkMaxModifTime = pChkDesc->stat.st_mtime; if( pChkDesc->chkMaxAccTime < pChkDesc->stat.st_atime ) pChkDesc->chkMaxAccTime = pChkDesc->stat.st_atime; /* recursively check directory */ if( (localFlHdl.attrib & DOS_ATTR_DIRECTORY) != 0 ) { if( pChkDesc->curPathLev == DOS_MAX_DIR_LEVELS ) { pChkDesc->nErrors ++; dosChkEntryDel( &localFd, TRUE, (u_char *)CHK_DIR_LVL_OVERFL, CURRENT_PATH, 0,0,0,0 ); continue; } pChkDesc->curPathLev ++; work1 = dosFsChkTree( &localFd ); pChkDesc->curPathLev --; if( work1 != CHK_OK ) { return work1; } } } /* for ... */ /* check, that device is OK yet */ if( TRUE == cbioRdyChgdGet (pFd->pVolDesc->pCbio) ) return CHK_ERROR; return CHK_OK; } /* dosFsChkTree() *//********************************************************************************* dosChkInit - allocate resources.** RETURNS: OK or ERROR if KHEAP_ALLOC failed.*/LOCAL STATUS dosChkInit ( DOS_FILE_DESC_ID pFd ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; void * chkFatMap; BOOL bufToDisk; if( pVolDesc->pChkDesc == NULL ) { /* allocate descriptor */ pVolDesc->pChkDesc = KHEAP_ALLOC((sizeof(*pVolDesc->pChkDesc))); if( pVolDesc->pChkDesc == NULL ) return ERROR; pVolDesc->pChkDesc->bufToDisk = FALSE; /* check memory size and allocate FAT buffer */ pVolDesc->pChkDesc->chkFatMap = NULL; /* do not remove this string */ if( ((u_long) (memFindMax()) <= (u_long) (pVolDesc->nFatEnts * sizeof (*pVolDesc->pChkDesc->chkFatMap) +32)) || (NULL == (pVolDesc->pChkDesc->chkFatMap = KHEAP_ALLOC( ((pVolDesc->nFatEnts) * (sizeof(*pVolDesc->pChkDesc->chkFatMap)))))) ) { /* * only FAT32 disks can use reserved FAT copy instead * of memory buffer */ if( (pVolDesc->fatType != FAT32) || (pVolDesc->pFatDesc->activeCopyNum == pVolDesc->nFats - 1) || ((pVolDesc->pChkDesc->chkFatMap = KHEAP_ALIGNED_ALLOC(\ (sizeof(*pVolDesc->pChkDesc->chkFatMap)),\ (pVolDesc->nFatEnts / 8 + 4))) == NULL)) { printf( CHK_NOT_ROOM_MSG, pVolDesc->devHdr.name ); dosChkFinish( pFd ); return ERROR; } pVolDesc->pChkDesc->bufToDisk = TRUE; } if( pVolDesc->chkVerbLevel >= (DOS_CHK_VERB_1 >> 8) ) dosChkMsg( pFd, CHK_START_MSG, GET_PATH, 0,0,0,0, NULL ); } chkFatMap = pVolDesc->pChkDesc->chkFatMap; bufToDisk = pVolDesc->pChkDesc->bufToDisk; bzero( (char *) pVolDesc->pChkDesc, sizeof( *pVolDesc->pChkDesc ) ); pVolDesc->pChkDesc->chkFatMap = chkFatMap; pVolDesc->pChkDesc->bufToDisk = bufToDisk; /* disable FAT mirroring */ pVolDesc->pFatDesc->syncToggle (pVolDesc, FALSE); /* zero FAT buffer */ dosChkEntryMark (pFd, MARK_BUF_INIT, 0, 0 ); return OK; } /* dosChkInit() */ /********************************************************************************* dosChkDsk - start disk check procedure.** RETURNS: OK or ERROR if device is not a valid DOS device,* corrections can not be written to disk* or disk read error.** NOMANUAL*/STATUS dosChkDsk ( DOS_FILE_DESC_ID pFd ) { CHK_STATUS result; size_t i; struct timespec tv; do { if( dosChkInit( pFd ) == ERROR ) return ERROR; pFd->pVolDesc->pChkDesc->curPathLev = 1; /* current path is just a device name */ strcpy( pFd->pVolDesc->pChkDesc->chkCurPath, pFd->pVolDesc->devHdr.name ); result = dosFsChkTree( pFd ); } while( result == CHK_RESTART ); /* clear current path from screen */ printf( "\r" ); for( i = 0; i < strlen( pFd->pVolDesc->pChkDesc->chkCurPath ); i ++ ) { printf( "%4c", SPACE ); } printf( "\r" ); if( result == CHK_ERROR ) goto ret; /* * set system clock to be later, than the last time on volume, * but only in case it seems a Real-Time Clock chip * not present */ if( time( NULL ) < dosChkMinDate ) { tv.tv_sec = max (dosChkMinDate, (max(pFd->pVolDesc->pChkDesc->chkMaxCreatTime, max(pFd->pVolDesc->pChkDesc->chkMaxModifTime, pFd->pVolDesc->pChkDesc->chkMaxAccTime)))); if( tv.tv_sec > time( NULL ) ) { tv.tv_nsec = time( NULL ); /* Let the user know we are adjusting the system time */ printf ("dosChkLib : "); printf("CLOCK_REALTIME is being reset to %s", ctime( &tv.tv_sec ) ); printf("Value obtained from file system volume " "descriptor pointer: %p\n", pFd->pVolDesc); tv.tv_nsec = time( NULL ); printf("The old setting was %s", ctime((time_t *)&tv.tv_nsec ) ); tv.tv_nsec = dosChkMinDate; printf("Accepted system dates are greater than %s", ctime((time_t *)&tv.tv_nsec)); tv.tv_nsec = 1; clock_settime( CLOCK_REALTIME, &tv ); } } /* before deal with lost chains, store all corrections to disk */ if(O_RDONLY != cbioModeGet(pFd->pVolDesc->pCbio)) { if( cbioIoctl (pFd->pVolDesc->pCbio, CBIO_CACHE_FLUSH, (void *)(-1) ) == ERROR ) { result = CHK_ERROR; goto ret; } } /* compose "current path" for attractive messages */ strcpy( pFd->pVolDesc->pChkDesc->chkCurPath, pFd->pVolDesc->devHdr.name ); strcat( pFd->pVolDesc->pChkDesc->chkCurPath, CHK_LOST_CHAINS_MSG ); if( dosChkLostFind( pFd ) == ERROR /* collect lost chains */ || pFd->pVolDesc->pChkDesc->nErrors > 0 ) { dosChkLostFree( pFd ); /* free/ count lost chains */ if( pFd->pVolDesc->chkLevel == DOS_CHK_ONLY ) { dosChkMsg( pFd, CHK_NOT_REPAIRED, GET_PATH, 0,0,0,0, NULL ); result = CHK_ERROR; } else if( pFd->pVolDesc->chkLevel >= DOS_CHK_REPAIR ) { dosChkMsg( pFd, CHK_RESTORE_FREE, GET_PATH, 0,0,0,0, NULL ); } } else { dosChkMsg( pFd, CHK_NO_ERRORS, GET_PATH, 0,0,0,0, NULL ); } /* set a random volume Id, if this initialized to a bad value */ if ((pFd->pVolDesc->chkLevel > DOS_CHK_ONLY) && ((pFd->pVolDesc->volId == 0) || (pFd->pVolDesc->volId == (u_int)(-1))) && (O_RDONLY != cbioModeGet(pFd->pVolDesc->pCbio))) { printf("Change volume Id from %p ", (void *)pFd->pVolDesc->volId ); VX_TO_DISK_32( tickGet(), &pFd->pVolDesc->volId ); cbioBytesRW (pFd->pVolDesc->pCbio, pFd->pVolDesc->bootSecNum, pFd->pVolDesc->volIdOff, (void *)&pFd->pVolDesc->volId, sizeof( pFd->pVolDesc->volId ), CBIO_WRITE, NULL ); pFd->pVolDesc->volId = DISK_TO_VX_32( &pFd->pVolDesc->volId ); printf("to %p\n", (void *)pFd->pVolDesc->volId ); } dosChkStatPrint( pFd ); ret: dosChkFinish( pFd ); /* If not write protected enable FAT mirroring and synchronize copies */ if ((pFd->pVolDesc->chkLevel > DOS_CHK_ONLY) && (O_RDONLY != cbioModeGet(pFd->pVolDesc->pCbio))) { pFd->pVolDesc->pFatDesc->syncToggle (pFd->pVolDesc, TRUE); } /* * !!! do not set cbioReadyChanged to TRUE here, * because dosFsLib has to synchronize cache before it */ return ( result == CHK_OK )? OK : ERROR; } /* dosChkDsk() */ /********************************************************************************* dosChkLibInit - install dos sanity check utility.** RETURNS: N/A.** NOMANUAL*/void dosChkLibInit( void ) { dosFsChkRtn = dosChkDsk; }/********************************************************************************* dosChkEntryMarkSet - mark entry if it is not market yet** RETURNS: if failed to mark the entry*/LOCAL STATUS dosChkEntryMarkSet ( DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ uint32_t entryNum, /* */ uint32_t markValue /* */ ) { uint32_t mark; /* Check entry status */ mark = dosChkEntryMark (pFd, MARK_GET, entryNum, 0); if (mark != 0) /* already marked entry */ return ERROR; /* Mark entry */ dosChkEntryMark (pFd, MARK_SET, entryNum, markValue); return OK; } /* dosChkEntryMarkSet *//********************************************************************************* dosChkChainMark - mark an entire chain** RETURNS: size of file represented by this chain*/LOCAL uint32_t dosChkChainMark (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -