library/src/filesystem/BP-FilesystemRegistry.cc
// USE THIS: Attempt to crawl the filesystem based on the registry configuration.  This should be used
// unless you've studied BP_FSRegCrawl_r and understand how to use it safely on it's own.  Basically,
// use this in all cases, don't use BP_FSRegCrawl_r directly.
USE THIS: Attempt to crawl the filesystem based on the registry configuration.  This should be used
unless you've studied BP_FSRegCrawl_r and understand how to use it safely on it's own.  Basically,
use this in all cases, don't use BP_FSRegCrawl_r directly.
USE THIS : Attempt to crawl the filesystem based on the registry configuration . This should be used unless you ' ve studied BP_FSRegCrawl_r and understand how to use it safely on it ' s own . Basically use this in all cases don ' t use BP_FSRegCrawl_r directly .
BP_ERROR_T BP_FSRegCrawl
(
		P_BP_FSREG fs_reg
)
{
	if(!fs_reg)
		return ERR_FAILURE;
	if(!fs_reg->hreg)
		return ERR_FAILURE;
	BP_HASH_TABLE_ENTER_CRITICAL_SECTION(fs_reg->hreg);
	if(!fs_reg->top_dir)
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	BP_FSREG_ENFORCE_LIMITS_CRITICAL_SECTION(fs_reg, ERR_FAILURE);
	%%%%%%%%
	%%%%%%%%
	if(bpstrlen(fs_reg->top_dir) == 1)
	if(fs_reg->top_dir[0] == '.')
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	if(bpstrlen(fs_reg->top_dir) == 2)
	if(fs_reg->top_dir[0] == '.')
	if(fs_reg->top_dir[1] == '.')
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	if(!BP_StringIsReasonableForUnixEXT4Directory(fs_reg->top_dir, bpstrlen(fs_reg->top_dir), BP_FALSE))
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	DIR *           dir              = NULL;
	struct dirent * dir_entry_result = NULL;
	struct dirent   dir_entry;
	BP_ZERO_STACK(dir_entry);
	dir = opendir(fs_reg->top_dir);
	if(!dir)
	{
		printf("\n [!!] %s could not be opened for filesystem walking.", fs_reg->top_dir);
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	}
	char * crawl_dir       = NULL;
	char * join_strings[4] = {0};
	size_t join_iter       = 0;
	char ** lookup_path = NULL;
	%%%%%%%%
	%%%%%%%%
	P_BP_HASH_TABLE_KEYED_ENTRY add_to_this_table = NULL;
	P_BP_HASH_TABLE_KEYED_ENTRY top_table         = NULL;
	char *initial_add_path[3] = {0};
	initial_add_path[0] = (char *) fs_reg->top_dir;
	initial_add_path[1] = NULL;
	BP_HashRegAddTableByPath(fs_reg->hreg, (char **) &initial_add_path);
	top_table = BP_HashRegLookupTableByPath(fs_reg->hreg, (char **) &initial_add_path);
	%%%%%%%%
	%%%%%%%%
	while
	(
		!readdir_r(dir, &dir_entry, &dir_entry_result)
	)
	{
		if(!dir_entry_result)
			break;
		switch(dir_entry.d_type)
		{
			case DT_DIR:
				%%%
				%%%
				if(!BP_StringIsReasonablePrintableString(dir_entry.d_name, strnlen(dir_entry.d_name, 255), BP_FALSE, BP_FALSE))
					BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
				if(bpstrlen(dir_entry.d_name) == 1)
				if(dir_entry.d_name[0] == '.')
					break;
				if(bpstrlen(dir_entry.d_name) == 2)
				if(dir_entry.d_name[0] == '.')
				if(dir_entry.d_name[1] == '.')
					break;
				if(strstr(dir_entry.d_name, "/"))
					break;
				%
				%
				join_iter = 0;
				join_strings[join_iter] = fs_reg->top_dir;
				join_iter++;
				if(fs_reg->top_dir[bpstrlen(fs_reg->top_dir)] == '/')
				{
						join_strings[join_iter] = "/";
						join_iter++;
				}
				join_strings[join_iter] = (char *) &dir_entry.d_name;
				join_iter++;
				crawl_dir = BP_JoinStringArray(join_strings, join_iter, NULL);
				if(crawl_dir)
				{
					initial_add_path[0] = (char *) fs_reg->top_dir;
					initial_add_path[1] = (char *) &dir_entry.d_name;
					initial_add_path[2] = NULL;
					BP_HashRegAddTableByPath(fs_reg->hreg, (char **) &initial_add_path);
					add_to_this_table = BP_HashRegLookupTableByPath(fs_reg->hreg, (char **) &initial_add_path);
					if(!add_to_this_table)
					{
						if(crawl_dir)
							bpfree(crawl_dir);
						BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
					}
					%
					%
					BP_FSRegAddRecord
					(
							fs_reg,
							add_to_this_table,
							&dir_entry
					);
					BP_ZERO_STACK(dir_entry);
					%
					%
					BP_FSRegCrawl_r(fs_reg, crawl_dir, add_to_this_table);
				}
				if(crawl_dir)
				{
					bpfree(crawl_dir);
					crawl_dir = NULL;
				}
				break;
			default:
				break;
		}
	}
	if(dir)
		closedir(dir);
	BP_FSREG_ENFORCE_LIMITS_CRITICAL_SECTION(fs_reg, ERR_FAILURE);
	%%%%%%%
	%%%%%%%
	DIR *           dir_inner              = NULL;
	struct dirent * dir_entry_inner_result = NULL;
	struct dirent   dir_entry_inner;
	BP_ZERO_STACK(dir_entry_inner);
	dir_inner = opendir(fs_reg->top_dir);
	if(!dir_inner)
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(fs_reg->hreg, ERR_FAILURE);
	while
	(
		!readdir_r(dir_inner, &dir_entry_inner, &dir_entry_inner_result)
	)
	{
		if(!dir_entry_inner_result)
			break;
		switch(dir_entry_inner.d_type)
		{
			case DT_REG:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			case DT_CHR:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			case DT_BLK:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			case DT_FIFO:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			case DT_LNK:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			case DT_SOCK:
				BP_FSRegAddRecord
				(
						fs_reg,
						(P_BP_HASH_TABLE_KEYED_ENTRY) top_table,
						&dir_entry_inner
				);
				BP_ZERO_STACK(dir_entry_inner);
				break;
			default:
				break;
		}
	}
	if(dir_inner)
	{
		closedir(dir_inner);
		dir_inner = NULL;
	}
	%%%%%%
	%%%%%%
	BP_HASH_TABLE_LEAVE_CRITICAL_SECTION(fs_reg->hreg);
	return ERR_SUCCESS;
}
BP_ERROR_T BP_FSRegCrawl ( P_BP_FSREG fs_reg ) { if ( ! fs_reg ) return ERR_FAILURE ; if ( ! fs_reg -> hreg ) return ERR_FAILURE ; BP_HASH_TABLE_ENTER_CRITICAL_SECTION ( fs_reg -> hreg ) ; if ( ! fs_reg -> top_dir ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; BP_FSREG_ENFORCE_LIMITS_CRITICAL_SECTION ( fs_reg , ERR_FAILURE ) ; if ( bpstrlen ( fs_reg -> top_dir ) == 1 ) if ( fs_reg -> top_dir [ 0 ] == ' ' ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; if ( bpstrlen ( fs_reg -> top_dir ) == 2 ) if ( fs_reg -> top_dir [ 0 ] == ' ' ) if ( fs_reg -> top_dir [ 1 ] == ' ' ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; if ( ! BP_StringIsReasonableForUnixEXT4Directory ( fs_reg -> top_dir , bpstrlen ( fs_reg -> top_dir ) , BP_FALSE ) ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; DIR * dir = NULL ; struct dirent * dir_entry_result = NULL ; struct dirent dir_entry ; BP_ZERO_STACK ( dir_entry ) ; dir = opendir ( fs_reg -> top_dir ) ; if ( ! dir ) { printf ( " \n " , fs_reg -> top_dir ) ; BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; } char * crawl_dir = NULL ; char * join_strings [ 4 ] = { 0 } ; size_t join_iter = 0 ; char * * lookup_path = NULL ; P_BP_HASH_TABLE_KEYED_ENTRY add_to_this_table = NULL ; P_BP_HASH_TABLE_KEYED_ENTRY top_table = NULL ; char * initial_add_path [ 3 ] = { 0 } ; initial_add_path [ 0 ] = ( char * ) fs_reg -> top_dir ; initial_add_path [ 1 ] = NULL ; BP_HashRegAddTableByPath ( fs_reg -> hreg , ( char * * ) & initial_add_path ) ; top_table = BP_HashRegLookupTableByPath ( fs_reg -> hreg , ( char * * ) & initial_add_path ) ; while ( ! readdir_r ( dir , & dir_entry , & dir_entry_result ) ) { if ( ! dir_entry_result ) break ; switch ( dir_entry . d_type ) { case DT_DIR : if ( ! BP_StringIsReasonablePrintableString ( dir_entry . d_name , strnlen ( dir_entry . d_name , 255 ) , BP_FALSE , BP_FALSE ) ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; if ( bpstrlen ( dir_entry . d_name ) == 1 ) if ( dir_entry . d_name [ 0 ] == ' ' ) break ; if ( bpstrlen ( dir_entry . d_name ) == 2 ) if ( dir_entry . d_name [ 0 ] == ' ' ) if ( dir_entry . d_name [ 1 ] == ' ' ) break ; if ( strstr ( dir_entry . d_name , " " ) ) break ; join_iter = 0 ; join_strings [ join_iter ] = fs_reg -> top_dir ; join_iter ++ ; if ( fs_reg -> top_dir [ bpstrlen ( fs_reg -> top_dir ) ] == ' ' ) { join_strings [ join_iter ] = " " ; join_iter ++ ; } join_strings [ join_iter ] = ( char * ) & dir_entry . d_name ; join_iter ++ ; crawl_dir = BP_JoinStringArray ( join_strings , join_iter , NULL ) ; if ( crawl_dir ) { initial_add_path [ 0 ] = ( char * ) fs_reg -> top_dir ; initial_add_path [ 1 ] = ( char * ) & dir_entry . d_name ; initial_add_path [ 2 ] = NULL ; BP_HashRegAddTableByPath ( fs_reg -> hreg , ( char * * ) & initial_add_path ) ; add_to_this_table = BP_HashRegLookupTableByPath ( fs_reg -> hreg , ( char * * ) & initial_add_path ) ; if ( ! add_to_this_table ) { if ( crawl_dir ) bpfree ( crawl_dir ) ; BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; } BP_FSRegAddRecord ( fs_reg , add_to_this_table , & dir_entry ) ; BP_ZERO_STACK ( dir_entry ) ; BP_FSRegCrawl_r ( fs_reg , crawl_dir , add_to_this_table ) ; } if ( crawl_dir ) { bpfree ( crawl_dir ) ; crawl_dir = NULL ; } break ; default : break ; } } if ( dir ) closedir ( dir ) ; BP_FSREG_ENFORCE_LIMITS_CRITICAL_SECTION ( fs_reg , ERR_FAILURE ) ; DIR * dir_inner = NULL ; struct dirent * dir_entry_inner_result = NULL ; struct dirent dir_entry_inner ; BP_ZERO_STACK ( dir_entry_inner ) ; dir_inner = opendir ( fs_reg -> top_dir ) ; if ( ! dir_inner ) BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( fs_reg -> hreg , ERR_FAILURE ) ; while ( ! readdir_r ( dir_inner , & dir_entry_inner , & dir_entry_inner_result ) ) { if ( ! dir_entry_inner_result ) break ; switch ( dir_entry_inner . d_type ) { case DT_REG : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; case DT_CHR : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; case DT_BLK : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; case DT_FIFO : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; case DT_LNK : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; case DT_SOCK : BP_FSRegAddRecord ( fs_reg , ( P_BP_HASH_TABLE_KEYED_ENTRY ) top_table , & dir_entry_inner ) ; BP_ZERO_STACK ( dir_entry_inner ) ; break ; default : break ; } } if ( dir_inner ) { closedir ( dir_inner ) ; dir_inner = NULL ; } BP_HASH_TABLE_LEAVE_CRITICAL_SECTION ( fs_reg -> hreg ) ; return ERR_SUCCESS ; }
USE THIS: Attempt to crawl the filesystem based on the registry configuration.
USE THIS : Attempt to crawl the filesystem based on the registry configuration .
// enter critical section before crawling // ensure we have a top directory // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Run Limit Checks %%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // enforce limits // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Run Preliminary Top Dir Checks %%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // ensure that the directory is not ./ // ensure that the directory is not ../ // ensure that we have a reasonable directory to open // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Open Directory %%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // directory and entity pointers (used in loop logic) // attempt to open the directory // generated crawl directory // exploded lookup path // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Attempt To Add Top Record %%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // added records // this is the initial addition path used for the initial table add // set initial path // attempt to add table to the registry // attempt to lookup the entry after addition // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Run Recursing Loop for Dirs %%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // read directory entries // if there is no result, break // store directory type, recurse here // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Run Initial Sanity Checks %%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // ensure that we have a reasonable directory to open // ensure that the directory is not ./ // ensure that the directory is not ../ // ensure that the directory doesn't somehow have a // forward slash in it. // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Join Path for Recursion %%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // reset join itero to zero // set strings to join (middle / is only set if not set previously) // add / to the joining strings // add new directory name // join the crawl directories // attempt to add table path // set initial path // attempt to add table to the registry // attempt to lookup the entry after addition // exit if data addition failed // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Add At Position %%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // attempt to add directory record within directory // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Crawl Recusion %%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // run recursing from top position (pass null pointer) // close the directory // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Run Second Limit Checks %%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // enforce limits // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Top Directory Additive Loop %%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // innter dir (when a directory is encountered, this is opened for // secondary inner parsing) // attempt to re-oopen the directory // read directory entries // break if there is no result // switch on the entry type // regular file type // attempt to add a regular file to the top table // record character type // attempt to add character device to the top table // record block character type // attempt to add block device to the top table // record fifo character type // attempt to add directory record to the top of the hive // record symlink file type // attempt to add symbolic link // record socket file type // attempt to add socket record to the top of the hive // break loop here // close the directory // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Exit Critical Section %%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // leave when crawling is finished // return indicating success