<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -33,16 +33,16 @@
 /*----------------------------------------------------------------------------*/
 /*--------Macros--------------------------------------------------------------*/
 /*Print debug messages here*/
-#define DEBUG_OUTPUT &quot;/var/log/nsmux.dbg&quot;
+#define DEBUG_OUTPUT &quot;/var/tmp/filterfs.dbg&quot;
 /*----------------------------------------------------------------------------*/
 #ifdef DEBUG
 	/*Initializes the log*/
-#	define INIT_LOG() nsmux_dbg = fopen(DEBUG_OUTPUT, &quot;wt&quot;)
+#	define INIT_LOG() filterfs_dbg = fopen(DEBUG_OUTPUT, &quot;wt&quot;)
 	/*Closes the log*/
-# define CLOSE_LOG() fclose(nsmux_dbg)
+# define CLOSE_LOG() fclose(filterfs_dbg)
 	/*Prints a debug message and flushes the debug output*/
-#	define LOG_MSG(fmt, args...) {fprintf(nsmux_dbg, fmt&quot;\n&quot;, ##args);\
-		fflush(nsmux_dbg);}
+#	define LOG_MSG(fmt, args...) {fprintf(filterfs_dbg, fmt&quot;\n&quot;, ##args);\
+		fflush(filterfs_dbg);}
 #else
 	/*Remove requests for debugging output*/
 #	define INIT_LOG()
@@ -54,7 +54,7 @@
 /*----------------------------------------------------------------------------*/
 /*--------Global Variables----------------------------------------------------*/
 /*The file to write debugging info to*/
-extern FILE * nsmux_dbg;
+extern FILE * filterfs_dbg;
 /*----------------------------------------------------------------------------*/
 
 #endif /*__DEBUG_H__*/</diff>
      <filename>debug.h</filename>
    </modified>
    <modified>
      <diff>@@ -162,7 +162,7 @@ lnode_path_construct
 	/*A temporary pointer to an lnode*/
 	lnode_t * n;
 	
-	/*While the root node of the proxy filesystem has not been reached*/
+	/*While the root node of the filterfs filesystem has not been reached*/
 	for(n = node; n &amp;&amp; n-&gt;dir; n = n-&gt;dir)
 		/*add the length of the name of `n` to `p_len` make some space for
 			the delimiter '/', if we are not approaching the root node*/
@@ -171,7 +171,7 @@ lnode_path_construct
 			add a '/'*/
 		p_len += n-&gt;name_len + 1;
 		
-	/*Include the space for the path to the root node of the proxy
+	/*Include the space for the path to the root node of the filterfs
 		(n is now the root of the filesystem)*/
 	p_len += strlen(n-&gt;path) + 1;
 		
@@ -185,7 +185,7 @@ lnode_path_construct
 		/*put a terminal 0 at the end of the path*/
 		p[--p_len] = 0;
 		
-		/*While the root node of the proxy filesystem has not been reached*/
+		/*While the root node of the filterfs filesystem has not been reached*/
 		for(n = node; n &amp;&amp; n-&gt;dir; n = n-&gt;dir)
 			{
 			/*compute the position where the name of `n` is to be inserted*/
@@ -194,7 +194,7 @@ lnode_path_construct
 			/*copy the name of the node into the path (omit the terminal 0)*/
 			strncpy(p + p_len, n-&gt;name, n-&gt;name_len);
 			
-			/*If we are not at the root node of the proxy filesystem, add the
+			/*If we are not at the root node of the filterfs filesystem, add the
 				separator*/
 			/*if(n-&gt;dir-&gt;dir)
 				p[--p_len] = '/';*/
@@ -303,70 +303,3 @@ lnode_uninstall
 		node-&gt;next-&gt;prevp = &amp;node-&gt;next;
 	}/*lnode_uninstall*/
 /*----------------------------------------------------------------------------*/
-/*Constructs a list of translators that were set on the ancestors of `node`*/
-error_t
-lnode_list_translators
-	(
-	lnode_t * node,
-	char ** trans,	/*the malloced list of 0-separated strings*/
-	size_t * ntrans	/*the number of elements in `trans`*/
-	)
-	{
-	/*The size of block of memory for the list of translators*/
-	size_t sz = 0;
-	
-	/*Used for tracing the lineage of `node`*/
-	lnode_t * ln = node;
-	
-	/*Used in computing the lengths of lists of translators in every node
-		we will go through and for constructing the final list of translators*/
-	char * p;
-	
-	/*The current position in *data (used in filling out the list of
-		translators)*/
-	char * transp;
-	
-	/*The length of the current translator name*/
-	size_t complen;
-	
-	size_t i;
-	
-	/*Trace the lineage of the `node` (including itself) and compute the
-		total length of the list of translators*/
-	for(; ln; sz += ln-&gt;translen, ln = ln-&gt;dir);
-	
-	/*Try to allocate a block of memory sufficient for storing the list of
-		translators*/
-	*trans = malloc(sz);
-	if(!*trans)
-		return ENOMEM;
-	
-	/*No translators at first*/
-	*ntrans = 0;
-	
-	/*Again trace the lineage of the `node` (including itself)*/
-	for(transp = *trans + sz, ln = node; ln; ln = ln-&gt;dir)
-		{
-		/*Go through each translator name in the list of names*/
-		for(i = 0, p = ln-&gt;trans + ln-&gt;translen - 2; i &lt; ln-&gt;ntrans; ++i)
-			{
-			/*position p at the beginning of the current component and
-				compute its length at the same time*/
-			for(complen = 0; *p; --p, ++complen);
-			--p;
-			
-			/*move the current position backwards*/
-			transp -= complen + 1;
-
-			/*copy the current translator name into the list*/
-			strcpy(transp, p + 2);
-			
-			/*we've got another translator*/
-			++*ntrans;
-			}
-		}
-		
-	/*Everything OK*/
-	return 0;
-	}/*lnode_list_translators*/
-/*----------------------------------------------------------------------------*/</diff>
      <filename>lnode.c</filename>
    </modified>
    <modified>
      <diff>@@ -48,17 +48,6 @@ struct lnode
 	/*the full path to the lnode*/
 	char * path;
 	
-	/*the malloced set of translators which have to be stacked upon this node
-	  and upon its children; the corresponding translators will have to decide
-	  on their own whether to accept directories or not*/
-	char * trans;
-	
-	/*the number of translators listed in `translators`*/
-	size_t ntrans;
-	
-	/*the length of the list of translators (in bytes)*/
-	size_t translen;
-
 	/*the associated flags*/
 	int flags;
 	
@@ -151,13 +140,4 @@ lnode_uninstall
 	lnode_t * node
 	);
 /*----------------------------------------------------------------------------*/
-/*Constructs a list of translators that were set on the ancestors of `node`*/
-error_t
-lnode_list_translators
-	(
-	lnode_t * node,
-	char ** trans,	/*the malloced list of 0-separated strings*/
-	size_t * ntrans	/*the number of elements in `trans`*/
-	);
-/*----------------------------------------------------------------------------*/
 #endif /*__LNODE_H__*/</diff>
      <filename>lnode.h</filename>
    </modified>
    <modified>
      <diff>@@ -37,7 +37,7 @@
 #include &quot;node.h&quot;
 #include &quot;options.h&quot;
 #include &quot;lib.h&quot;
-#include &quot;nsmux.h&quot;
+#include &quot;filterfs.h&quot;
 /*----------------------------------------------------------------------------*/
 
 /*----------------------------------------------------------------------------*/
@@ -311,6 +311,168 @@ node_entries_get
 	{
 	error_t err = 0;
 
+	/*Obtain the path to the current node*/
+	char * path_to_node = node-&gt;nn-&gt;lnode-&gt;path;
+	
+	/*The number of PROPERTY_PARAMs in the property*/
+	int param_entries_count = 0;
+	
+	/*The length of the property*/
+	size_t property_len = (property) ? (strlen(property)) : (0);
+	
+	/*The length of PROPERTY_PARAM*/
+	size_t property_param_len = strlen(PROPERTY_PARAM);
+
+	/*The full name and the filtering command*/
+	char * full_name = NULL, * cmd = NULL;
+
+	/*The lengths of the full name and the filtering command in chunks*/
+	size_t full_name_size = 1, cmd_size = 1;
+
+	/*If some property was indeed specified*/
+	if(property_len != 0)
+		{
+		/*the pointer to the current occurrence of PROPERTY_PARAM*/
+		char * occurrence = strstr(property, PROPERTY_PARAM);
+		
+		/*count the number of occurrences*/
+		for(; occurrence;
+			occurrence = strstr(occurrence + 1, PROPERTY_PARAM),
+			++param_entries_count);
+
+		/*try allocate the memory for the fullname and the filtering command*/
+		full_name = malloc(full_name_size * STRING_CHUNK);
+		if(!full_name)
+			return ENOMEM;
+
+		cmd = malloc(cmd_size * STRING_CHUNK);
+		if(!cmd)
+			{
+			free(full_name);
+			return ENOMEM;
+			}
+		}
+
+	/*Obtain the length of the path*/
+	size_t pathlen = strlen(path_to_node);
+
+	/*Checks if the given file satisfies the property. Zero value means that
+		the entry must be filtered out*/
+	int
+	check_property
+		(
+		const char * name	/*the name of the file*/
+		)
+		{
+		/*If there is no property*/
+		if(!property)
+			/*no filtering will be applied, any name is OK*/
+			return 0;
+		
+		/*Everything OK at first*/
+		err = 0;
+		
+		/*Compute the length of the full name once*/
+		size_t full_name_len = pathlen + 1 + strlen(name) + 1;
+
+		/*See how much space (in chunks) is required for the full name*/
+		int chunks = full_name_size;
+		for(; full_name_len &gt; chunks * STRING_CHUNK; ++chunks);
+		
+		/*If more memory is requied*/
+		if(chunks &gt; full_name_size)
+			{
+			/*free the old full name*/
+			free(full_name);
+
+			/*try to allocate the new memory*/
+			full_name = malloc(chunks * STRING_CHUNK);
+			if(!full_name)
+				{
+				err = ENOMEM;
+				free(cmd); /*the string for the command is definitely allocated here*/
+				return 0;
+				}
+			
+			/*store the new size*/
+			full_name_size = chunks;
+			}
+		
+		/*Initialize `full_name` as a valid string*/
+		full_name[0] = 0;
+		
+		/*Construct the full name*/
+		strcpy(full_name, path_to_node);
+		strcat(full_name, &quot;/&quot;);
+		strcat(full_name, name);
+		
+		/*LOG_MSG(&quot;node_entries_get: Applying filter to %s...&quot;, full_name);*/
+		
+		/*Compute the space required for the final filtering command*/
+		size_t sz = property_len + (strlen(full_name) - property_param_len)
+			* param_entries_count;
+		
+		/*See how much space (in chunks) is required for the command*/
+		for(chunks = cmd_size; sz &gt; chunks * STRING_CHUNK; ++chunks);
+		
+		/*If more memory is requied*/
+		if(chunks &gt; cmd_size)
+			{
+			/*free the old command*/
+			free(cmd);
+
+			/*try to allocate the new memory*/
+			cmd = malloc(chunks * STRING_CHUNK);
+			if(!cmd)
+				{
+				err = ENOMEM;
+				free(full_name);	/*the string for the full name is
+														definitely allocated here*/
+				return 0;
+				}
+			
+			/*store the new size*/
+			cmd_size = chunks;
+			}
+
+		/*Initialize `cmd` as a valid string*/
+		cmd[0] = 0;
+			
+		/*The current occurence of PROPERTY_PARAM in property*/
+		char * p = strstr(property, PROPERTY_PARAM);
+		
+		/*The pointer to the current position in the property*/
+		char * propp = property;
+		
+		/*While the command has not been constructed*/
+		for(; p; p = strstr(propp, PROPERTY_PARAM))
+			{
+			/*add the new part of the property to the command*/
+			strncat(cmd, propp, p - propp);
+			
+			/*add the filename to the command*/
+			strcat(cmd, full_name);
+			
+			/*LOG_MSG(&quot;\tcmd = '%s'&quot;, cmd);*/
+
+			/*advance the pointer in the property*/
+			propp = p + property_param_len;
+
+			/*LOG_MSG(&quot;\tpropp points at '%s'&quot;, propp);*/
+			}
+		
+		/*Copy the rest of the property to the command*/
+		strcat(cmd, propp);
+		
+		/*LOG_MSG(&quot;node_entries_get: The filtering command: '%s'.&quot;, cmd);*/
+
+		/*Execute the command*/
+		int xcode = WEXITSTATUS(system(cmd));
+		
+		/*Return the exit code of the command*/
+		return xcode;
+		}/*check_property*/
+
 	/*The list of dirents*/
 	struct dirent ** dirent_list, **dirent;
 	
@@ -348,6 +510,9 @@ node_entries_get
 	/*The size of the current dirent*/
 	size_t size;
 	
+	/*The exit code of property*/
+	int good;
+	
 	/*Go through all elements of the list of pointers to dirent*/
 	for(dirent = dirent_list; *dirent; ++dirent)
 		{
@@ -358,6 +523,15 @@ node_entries_get
 		if((strcmp(name, &quot;.&quot;) == 0) ||	(strcmp(name, &quot;..&quot;) == 0))
 			continue;
 		
+		/*check if the current dirent has the property*/
+		good = check_property(name);
+		if(err)
+			break;
+ 		
+		/*If the current entry is not good, skip it*/
+		if(good != 0)
+			continue;
+		
 		/*obtain the length of the current name*/
 		name_len = strlen(name);
 		
@@ -407,6 +581,12 @@ node_entries_get
 	/*Free the results of listing the dirents*/
 	munmap(dirent_data, dirent_data_size);
 
+	/*Free the full name and the command (if these are present at all)*/
+	if(full_name)
+		free(full_name);
+	if(cmd)
+		free(cmd);
+	
 	/*Return the result of operations*/
 	return err;
 	}/*node_entries_get*/
@@ -463,7 +643,7 @@ node_update
 		return err;
 		}
 	
-	/*If the node looked up is actually the root node of the proxy filesystem*/
+	/*If the node looked up is actually the root node of filterfs filesystem*/
 	if
 		(
 		(stat.st_ino == underlying_node_stat.st_ino)
@@ -494,7 +674,7 @@ node_update
 	node-&gt;nn-&gt;flags &amp;= ~FLAG_NODE_INVALIDATE;
 	node-&gt;nn-&gt;flags |= FLAG_NODE_ULFS_UPTODATE;
 	
-	/*Release the lock on the root node of proxy filesystem*/
+	/*Release the lock on the root node of filterfs filesystem*/
 	mutex_unlock(&amp;netfs_root_node-&gt;lock);
 	
 	/*Return the result of operations*/</diff>
      <filename>node.c</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@
 
 /*----------------------------------------------------------------------------*/
 /*--------Macros--------------------------------------------------------------*/
-/*Checks whether the give node is the root of the proxy filesystem*/
+/*Checks whether the give node is the root of the filterfs filesystem*/
 #define NODE_IS_ROOT(n) (((n)-&gt;nn-&gt;lnode-&gt;dir) ? (0) : (1))
 /*----------------------------------------------------------------------------*/
 /*Node flags*/</diff>
      <filename>node.h</filename>
    </modified>
    <modified>
      <diff>@@ -40,9 +40,8 @@
 /*--------Macros--------------------------------------------------------------*/
 /*Short documentation for argp*/
 #define ARGS_DOC	&quot;DIR&quot;
-#define DOC 			&quot;Provides namespace-based translator selection.&quot;\
-	&quot; You can dynamically obtain the file 'file' translated by translator&quot;\
-	&quot; 'x' using the syntax: 'file,,x'.&quot;
+#define DOC 			&quot;Shows the contents of DIR filtered according to PROPERTY.\
+ If DIR is not specified, ~/ is assumed.&quot;
 /*----------------------------------------------------------------------------*/
 
 /*----------------------------------------------------------------------------*/
@@ -73,7 +72,7 @@ argp_parse_startup_options
 /*This variable is set to a non-zero value after the parsing of starup options
 	is finished*/
 /*Whenever the argument parser is later called to modify the
-	options of the root node will be initialized accordingly directly
+	options of filterfs the root node will be initialized accordingly directly
 	by the parser*/
 static int parsing_startup_options_finished;
 /*----------------------------------------------------------------------------*/
@@ -81,10 +80,12 @@ static int parsing_startup_options_finished;
 static const struct argp_option argp_common_options[] =
 	{
 	{OPT_LONG_CACHE_SIZE, OPT_CACHE_SIZE, &quot;SIZE&quot;, 0,
-		&quot;The maximal number of nodes in the node cache&quot;}
+		&quot;The maximal number of nodes in the node cache&quot;},
+	{OPT_LONG_PROPERTY, OPT_PROPERTY, &quot;PROPERTY&quot;, 0,
+		&quot;The command which will act as a filter&quot;}
 	};
 /*----------------------------------------------------------------------------*/
-/*Argp options only meaningful for startup parsing*/
+/*Argp options only meaningful for startupp parsing*/
 static const struct argp_option argp_startup_options[] =
 	{
 	{0}
@@ -126,7 +127,10 @@ struct argp argp_runtime =
 struct argp argp_startup =
 	{0, 0, ARGS_DOC, DOC, argp_children_startup};
 /*----------------------------------------------------------------------------*/
-/*The directory to mirror*/
+/*The filtering command*/
+char * property = NULL;
+/*----------------------------------------------------------------------------*/
+/*The directory to filter*/
 char * dir = NULL;
 /*----------------------------------------------------------------------------*/
 
@@ -154,7 +158,16 @@ argp_parse_common_options
 			
 			break;
 			}
-		case ARGP_KEY_ARG: /*the directory to mirror*/
+		case OPT_PROPERTY:
+			{
+			/*try to duplicate the filtering command*/
+			property = strdup(arg);
+			if(!property)
+				error(EXIT_FAILURE, ENOMEM, &quot;Could not strdup the property&quot;);
+				
+			break;
+			}
+		case ARGP_KEY_ARG: /*the directory to filter*/
 			{
 			/*try to duplicate the directory name*/
 			dir = strdup(arg);
@@ -172,7 +185,7 @@ argp_parse_common_options
 				/*put 0 instead*/
 				dir[i] = 0;
 				
-			LOG_MSG(&quot;argp_parse_common_options: Mirroring the directory %s.&quot;, dir);
+			LOG_MSG(&quot;argp_parse_common_options: Filtering the directory %s.&quot;, dir);
 
 			break;
 			}</diff>
      <filename>options.c</filename>
    </modified>
    <modified>
      <diff>@@ -30,13 +30,19 @@
 /*--------Macros--------------------------------------------------------------*/
 /*The possible short options*/
 #define OPT_CACHE_SIZE 'c'
+/*the property according to which filtering will be performed*/
+#define OPT_PROPERTY	 'p'
 /*----------------------------------------------------------------------------*/
 /*The corresponding long options*/
 #define OPT_LONG_CACHE_SIZE &quot;cache-size&quot;
+#define OPT_LONG_PROPERTY 	&quot;property&quot;
 /*----------------------------------------------------------------------------*/
 /*Makes a long option out of option name*/
 #define OPT_LONG(o) &quot;--&quot;o
 /*----------------------------------------------------------------------------*/
+/*The substring of the property which shall be replaced by the filename*/
+#define PROPERTY_PARAM &quot;{}&quot;
+/*----------------------------------------------------------------------------*/
 
 /*----------------------------------------------------------------------------*/
 /*--------Global Variables----------------------------------------------------*/
@@ -49,7 +55,10 @@ extern struct argp argp_runtime;
 /*The number of nodes in cache (see ncache.{c,h})*/
 extern int ncache_size;
 /*----------------------------------------------------------------------------*/
-/*The directory to mirror*/
+/*The filtering command*/
+extern char * property;
+/*----------------------------------------------------------------------------*/
+/*The directory to filter*/
 extern char * dir;
 /*----------------------------------------------------------------------------*/
 #endif /*__OPTIONS_H__*/</diff>
      <filename>options.h</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>nsmux.c</filename>
    </removed>
    <removed>
      <filename>nsmux.h</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>a7a503d0d6ee62f10a9b2b943fd578543a04a12f</id>
    </parent>
  </parents>
  <author>
    <name>Sergiu Ivanov</name>
    <email>unlimitedscolobb@gmail.com</email>
  </author>
  <url>http://github.com/scolobb/filterfs/commit/06cad39d9796206997c028483fb54214899c43df</url>
  <id>06cad39d9796206997c028483fb54214899c43df</id>
  <committed-date>2008-07-18T14:39:50-07:00</committed-date>
  <authored-date>2008-07-18T14:39:50-07:00</authored-date>
  <message>Sorry! The previous push was erroneous...</message>
  <tree>6be1b4e6f8efc5d4a049ca7aa3ab7154d09515c4</tree>
  <committer>
    <name>Sergiu Ivanov</name>
    <email>unlimitedscolobb@gmail.com</email>
  </committer>
</commit>
