Exemple #1
0
cell_t *
surd_p_symbolp(surd_t *s, cell_t *args)
{
  cell_t *c;
  if (surd_list_length(s, args) == 1) {
    c = CAR(args);
    if (ISSYM(c)) {
      return c;
    }
    return s->nil;
  }
  else {
    fprintf(stderr, "arity error: symbol? takes 1 argument\n");
    exit(1);
  }
  return s->nil;
}
Exemple #2
0
// ----------------------------------------------------------------------
// Get file snap shot
// ----------------------------------------------------------------------
VOID GetFilesSnap(LPSNAPSHOT lpShot, LPTSTR lpszFullName, LPFILECONTENT lpFatherFC, LPFILECONTENT *lplpCaller) 
{
	LPFILECONTENT lpFC;
	HANDLE hFile;
	BOOL calculateHash = TRUE;
	BOOL found = FALSE;

	// Full dir/file name is already given
	// Extra local block to reduce stack usage due to recursive calls
	{
		LPTSTR lpszFindFileName;
		lpszFindFileName = NULL;
		// Get father file data if not already provided (=called from FileShot)
		// lpFatherFC only equals "C:\" and is called once at start
		if (NULL == lpFatherFC) 
		{
			// Check if file is to be GENERIC excluded
			if ((NULL == lpszFullName)
				|| (((TCHAR)'.' == lpszFullName[0])  // fast exclusion for 99% of the cases
				&& ((0 == _tcscmp(lpszFullName, TEXT(".")))
				|| (0 == _tcscmp(lpszFullName, TEXT("..")))))) {
				return;
			}
			// Create new file content
			lpFatherFC = MYALLOC0(sizeof(FILECONTENT));

			// Set file name length
			lpFatherFC->cchFileName = _tcslen(lpszFullName);
			// Copy file name to new buffer for directory search and more
			lpszFindFileName = MYALLOC((lpFatherFC->cchFileName + 4 + 1) * sizeof(TCHAR));  // +4 for "\*.*" search when directory (later in routine)
			_tcscpy(lpszFindFileName, lpszFullName);
			// Special case if root dir of a drive was specified, needs trailing backslash otherwise current dir of that drive is used
			if ((TCHAR)':' == lpszFindFileName[lpFatherFC->cchFileName - 1]) {
				lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\\';
				lpszFindFileName[lpFatherFC->cchFileName + 1] = (TCHAR)'\0';
			}
			//printf("lpszFullName: %ws\n", lpszFullName);
			//printf("lpszFindFileName: %ws\n", lpszFindFileName);

			hFile = FindFirstFile(lpszFullName, &FindData);
			if (INVALID_HANDLE_VALUE != hFile) {
				FindClose(hFile);
			}
			else {
				// Workaround for some cases in Windows Vista and later
				ZeroMemory(&FindData, sizeof(FindData));
				
				hFile = CreateFile(lpszFullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
				if (INVALID_HANDLE_VALUE != hFile) {
					BY_HANDLE_FILE_INFORMATION FileInformation;
					BOOL bResult;

					bResult = GetFileInformationByHandle(hFile, &FileInformation);
					if (bResult) {
						FindData.dwFileAttributes = FileInformation.dwFileAttributes;
						FindData.ftCreationTime = FileInformation.ftCreationTime;
						FindData.ftLastAccessTime = FileInformation.ftLastAccessTime;
						FindData.ftLastWriteTime = FileInformation.ftLastWriteTime;
						FindData.nFileSizeHigh = FileInformation.nFileSizeHigh;
						FindData.nFileSizeLow = FileInformation.nFileSizeLow;
					}
					else {
						FindData.dwFileAttributes = GetFileAttributes(lpszFullName);
						if (INVALID_FILE_ATTRIBUTES == FindData.dwFileAttributes) {
							FindData.dwFileAttributes = 0;
						}
						bResult = GetFileTime(hFile, &FindData.ftCreationTime, &FindData.ftLastAccessTime, &FindData.ftLastWriteTime);
						if (!bResult) {
							FindData.ftCreationTime.dwLowDateTime = 0;
							FindData.ftCreationTime.dwHighDateTime = 0;
							FindData.ftLastAccessTime.dwLowDateTime = 0;
							FindData.ftLastAccessTime.dwHighDateTime = 0;
							FindData.ftLastWriteTime.dwLowDateTime = 0;
							FindData.ftLastWriteTime.dwHighDateTime = 0;
						}
						FindData.nFileSizeLow = GetFileSize(hFile, &FindData.nFileSizeHigh);
						if (INVALID_FILE_SIZE == FindData.nFileSizeLow) {
							FindData.nFileSizeHigh = 0;
							FindData.nFileSizeLow = 0;
						}
					}
					CloseHandle(hFile);
				}
			}

			// Remove previously added backslash (if any)
			lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\0';

			// Copy pointer to current file into caller's pointer
			if (NULL != lplpCaller) {
				*lplpCaller = lpFatherFC;
			}
			          
			// Increase dir/file count
			if (ISFILE(FindData.dwFileAttributes)) {
				lpShot->stCounts.cFiles++;
			}
			else {
				lpShot->stCounts.cDirs++;
			}

			// Copy file name
			lpFatherFC->lpszFileName = MYALLOC((lpFatherFC->cchFileName + 1) * sizeof(TCHAR));
			_tcscpy(lpFatherFC->lpszFileName, lpszFullName);

			// Copy file data
			lpFatherFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
			lpFatherFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
			lpFatherFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
			lpFatherFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
			lpFatherFC->nFileSizeLow = FindData.nFileSizeLow;
			lpFatherFC->nFileSizeHigh = FindData.nFileSizeHigh;
			lpFatherFC->nFileAttributes = FindData.dwFileAttributes;

			// Set "lpFirstSubFC" pointer for storing the first child's pointer
			lplpCaller = &lpFatherFC->lpFirstSubFC;
		}

		// If father is a file, then leave (=special case when called from FileShot)
		if (ISFILE(lpFatherFC->nFileAttributes)) {
			if (NULL != lpszFindFileName) {
				MYFREE(lpszFindFileName);
			}
			return;
		}

		// Process all entries of directory
		// a) Create search pattern and start search
		if (NULL == lpszFindFileName) {
			lpszFindFileName = lpszFullName;
		}
		_tcscat(lpszFindFileName, TEXT("\\*.*"));
		hFile = FindFirstFile(lpszFindFileName, &FindData);
		if (lpszFindFileName != lpszFullName) {
			MYFREE(lpszFindFileName);
		}
	}  // End of extra local block
	if (INVALID_HANDLE_VALUE == hFile) {  
		// error: nothing in dir, no access, etc.
		//printf(">>> ERROR: fileshot.c: getFileSnap: INVALID_HANDLE_VALUE: %ws\n", lpszFullName);
		return;
	}
	// b) process entry then find next
	do {
		lpszFullName = NULL;
		//BOOL calculateHash = TRUE;
		//BOOL found = FALSE;

		// Check if file is to be GENERIC excluded (dot dirs)
		if ((NULL == FindData.cFileName)
			|| (((TCHAR)'.' == FindData.cFileName[0])  // fast exclusion for 99% of the cases
			&& ((0 == _tcscmp(FindData.cFileName, TEXT(".")))
			|| (0 == _tcscmp(FindData.cFileName, TEXT("..")))))) {
			continue;  // ignore this entry and continue with next file
		}

		// Create new file content
		lpFC = MYALLOC0(sizeof(FILECONTENT));
		// Set father of current key
		lpFC->lpFatherFC = lpFatherFC;
		// Set file name length
		lpFC->cchFileName = _tcslen(FindData.cFileName);

		// Allocate memory copy file name to FILECONTENT
		lpFC->lpszFileName = MYALLOC0((lpFC->cchFileName + 1) * sizeof(TCHAR));
		_tcscpy(lpFC->lpszFileName, FindData.cFileName);

		// Static blacklist for directories
		if (ISDIR(FindData.dwFileAttributes))
		{
			if (performStaticBlacklisting)
			{
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);

				found = TrieSearchPath(blacklistDIRS->children, lpszFullPath);
				if (found)
				{
					lpShot->stCounts.cFilesBlacklist++;
					MYFREE(lpszFullPath);
					FreeAllFileContents(lpFC);

					// Increase value count for display purposes
					lpShot->stCounts.cDirsBlacklist++;
					
					// Ignore this entry and continue with next brother value
					continue;  
				}
				else
				{
					MYFREE(lpszFullPath);
				}
			}
		}

		// Check if the file system entry is a symbolic link
		// If so, skip as it actually resides somewhere else on the file system!
		if (ISSYM(FindData.dwFileAttributes)) {
			if (ISFILE(FindData.dwFileAttributes)) {
				lpShot->stCounts.cFilesBlacklist++;
			}
			else {
				lpShot->stCounts.cDirsBlacklist++;
			}
			continue;
		}

		// Blacklisting implementation for files		
		if (ISFILE(FindData.dwFileAttributes))
		{
			if (dwBlacklist == 1)
			{
				// First snapshot, therefore populate the Trie (Prefix Tree)
				// Get the full file path
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);

				// Add full path to file blacklist prefix tree, then free path
				TrieAdd(&blacklistFILES, lpszFullPath);
				MYFREE(lpszFullPath);

				// Increase value count for display purposes
				lpShot->stCounts.cFiles++;

				// Ignore this entry and continue with next brother value
				//continue;  
			}
			else if (dwBlacklist == 2)
			{
				// Not the first snapshot, so either:
				// 1) If blacklisting enabled: Ignore file if its in the blacklist
				// 2) If hashing enabled (and not blacklisting): Mark file as not to be hashed
				LPTSTR lpszFullPath;
				lpszFullPath = GetWholeFileName(lpFC, 4);
				found = TrieSearchPath(blacklistFILES->children, lpszFullPath);
				if (found)
				{
					if (performDynamicBlacklisting)
					{
						MYFREE(lpszFullPath);
						FreeAllFileContents(lpFC);

						// Increase value count for display purposes
						lpShot->stCounts.cFilesBlacklist++;

						// Ignore this entry and continue with next brother value
						continue;  
					}
					if (performSHA1Hashing || performMD5Hashing)
					{
						lpShot->stCounts.cFiles++;
						MYFREE(lpszFullPath);
						calculateHash = FALSE;
					}
				}
				else
				{
					MYFREE(lpszFullPath);
				}
			}
		}
					
		// Copy pointer to current file into caller's pointer
		if (NULL != lplpCaller) {
			*lplpCaller = lpFC;
		}

		// Increase dir/file count
		if (ISFILE(FindData.dwFileAttributes)) {
			lpShot->stCounts.cFiles++;
		}
		else {
			lpShot->stCounts.cDirs++;
		}

		// Copy file data
		lpFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
		lpFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
		lpFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime;
		lpFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime;
		lpFC->nFileSizeLow = FindData.nFileSizeLow;
		lpFC->nFileSizeHigh = FindData.nFileSizeHigh;
		lpFC->nFileAttributes = FindData.dwFileAttributes;

		// Calculate file hash (computationally intensive!)
		// This should only be executed in the following scenarios:
		// 1) If the file system entry is a data file 
		// 2) If the data file is not blacklisted (previously known)
		if (ISFILE(FindData.dwFileAttributes))
		{
			if (dwBlacklist == 2 && calculateHash) {
			    if (performSHA1Hashing)
			    {
				    lpFC->cchSHA1 = 40;
				    lpFC->lpszSHA1 = MYALLOC((lpFC->cchSHA1 + 1) * sizeof(TCHAR));
				    _tcscpy(lpFC->lpszSHA1, CalculateSHA1(GetWholeFileName(lpFC, 4)));
                }
                if (performMD5Hashing)
                {
				    lpFC->cchMD5 = 32;
				    lpFC->lpszMD5 = MYALLOC((lpFC->cchMD5 + 1) * sizeof(TCHAR));
				    _tcscpy(lpFC->lpszMD5, CalculateMD5(GetWholeFileName(lpFC, 4)));
				}
				if (performMD5BlockHashing)
				{
					LPMD5BLOCK theMD5Block = CalculateMD5Blocks(GetWholeFileName(lpFC, 4), dwHashBlockSize);
					lpFC->lpMD5Block = MYALLOC0(sizeof(MD5BLOCK));
					lpFC->lpMD5Block = theMD5Block;
				}
			}
		}

		// Print file system shot status
		if ((dwBlacklist == 2 && performDynamicBlacklisting) || (performStaticBlacklisting)) {
			printf("  > Dirs: %d  Files: %d  Blacklisted Dirs: %d  Blacklisted Files: %d\r", lpShot->stCounts.cDirs, 
				lpShot->stCounts.cFiles,
				lpShot->stCounts.cDirsBlacklist,
				lpShot->stCounts.cFilesBlacklist);
		}
		else {
			printf("  > Dirs: %d  Files: %d\r", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles);
		}

		// ATTENTION!!! FindData will be INVALID from this point on, due to recursive calls
		// If the entry is a directory, then do a recursive call for it
		// Pass this entry as father and "lpFirstSubFC" pointer for storing the first child's pointer
		if (ISDIR(lpFC->nFileAttributes)) {
			if (NULL == lpszFullName) {
				lpszFullName = GetWholeFileName(lpFC, 4);  // +4 for "\*.*" search (in recursive call)
			}
			GetFilesSnap(lpShot, lpszFullName, lpFC, &lpFC->lpFirstSubFC);
		}

		if (NULL != lpszFullName) {
			MYFREE(lpszFullName);
		}

		// Set "lpBrotherFC" pointer for storing the next brother's pointer
		lplpCaller = &lpFC->lpBrotherFC;
	} while (FindNextFile(hFile, &FindData));
	FindClose(hFile);
}