diff --git a/Sharp.Augeas.Test/AugeasTests.cs b/Sharp.Augeas.Test/AugeasTests.cs
index 3a82049..be8776f 100644
--- a/Sharp.Augeas.Test/AugeasTests.cs
+++ b/Sharp.Augeas.Test/AugeasTests.cs
@@ -1,4 +1,5 @@
using System.Text;
+using System.Text.RegularExpressions;
namespace Sharp.Augeas.Test;
@@ -29,11 +30,10 @@ public class AugeasTests
}
[Test]
- public void NoExceptionThrownWhenPrintingVirtualhostTree()
+ public void GetTreeHasDirectivesAndArguments()
{
- var virtualHostConfig = EXAMPLE_CONF_1;
- _augeas.PrintVirtualHostTree(virtualHostConfig);
- Assert.Pass();
+ var tree = _augeas.GetTree("VirtualHost", $"/files{EXAMPLE_CONF_1}/VirtualHost/*");
+ Assert.That(tree.Arguments.Count > 0 && tree.Directives.Count > 0);
}
[Test]
@@ -75,6 +75,7 @@ public class AugeasTests
{
Assert.Fail("Unable to write changes to disk.");
}
+
var retrieveVal = _augeas.GetNode(nodePath);
Assert.That(retrieveVal == newValue);
}
@@ -99,7 +100,6 @@ public class AugeasTests
}
-
[Test]
public void MatchCanReturnMultipleDirectives()
{
@@ -108,13 +108,4 @@ public class AugeasTests
Assert.That(sites.Length > 0);
}
-
- [Test]
- public void GetTreeVirtualHostReturnsDictionaryWithKeys()
- {
- var path = EXAMPLE_CONF_1;
- var tree = _augeas.GetVirtualHostTree(path);
- Assert.That(tree.Count > 0);
- }
-
}
\ No newline at end of file
diff --git a/Sharp.Augeas/Augeas/Augeas.cs b/Sharp.Augeas/Augeas/Augeas.cs
index eb76c89..fe691ef 100644
--- a/Sharp.Augeas/Augeas/Augeas.cs
+++ b/Sharp.Augeas/Augeas/Augeas.cs
@@ -1,4 +1,6 @@
-using System.Runtime.InteropServices;using Sharp.Augeas.Test;
+using System.Runtime.InteropServices;
+using System.Text;
+using Sharp.Augeas.Test;
using static Sharp.Augeas.AugeasExtern;
namespace Sharp.Augeas
@@ -8,12 +10,13 @@ namespace Sharp.Augeas
///
public sealed unsafe class Augeas
{
-
#region Flags
+
///
///
///
public static int NONE = 0;
+
public static int SAVE_BACKUP = (1 << 0);
public static int SAVE_NEWFILE = (1 << 1);
public static int TYPE_CHECK = (1 << 2);
@@ -23,22 +26,23 @@ namespace Sharp.Augeas
public static int NO_MODL_AUTOLOAD = (1 << 6);
public static int AUG_ENABLE_SPAN = (1 << 7);
+
#endregion Flags
-
+
private readonly IntPtr _augeas;
private HashSet _loadedFiles = new();
#region Constructor / Destructor
-
+
///
/// Augeas Core Destructor
///
~Augeas()
- {
+ {
close_aug(_augeas);
}
-
+
///
/// Augeas Core constructor
///
@@ -60,7 +64,7 @@ namespace Sharp.Augeas
public Augeas(string root)
{
var lensPath = Environment.GetEnvironmentVariable("AUG_LENS_PATH");
-
+
if (string.IsNullOrEmpty(lensPath))
{
throw new InvalidOperationException(
@@ -68,21 +72,19 @@ namespace Sharp.Augeas
}
var augSettings = new AugSettings(root, lensPath);
-
+
_augeas = init_aug(augSettings, NO_STDINC | NO_LOAD);
-
+
if (_augeas == IntPtr.Zero)
{
throw new InvalidOperationException("Augeas is not a valid instance.");
}
}
-
#endregion
#region Augeas Internal Api
-
///
/// Prints a preview of the desired segment in
///
@@ -114,7 +116,7 @@ namespace Sharp.Augeas
{
return true;
}
-
+
bool success = load_file(_augeas, configurationFilePath);
_loadedFiles.Add(configurationFilePath);
@@ -145,9 +147,9 @@ namespace Sharp.Augeas
///
/// Configuration path.
/// Dictionary with the Tree
- private Dictionary GetTree(string matchPath)
+ public Dictionary GetDictionaryTree(string matchPath)
{
- var result = new Dictionary();
+ var result = new Dictionary();
var raw = get_tree(_augeas, matchPath);
string sb = Marshal.PtrToStringAnsi(raw);
var lines = sb.Split(";ENDL;");
@@ -159,6 +161,7 @@ namespace Sharp.Augeas
result.Add(pair[0].Remove(0, 3), pair[1]);
}
}
+
FreeString(raw);
return result;
}
@@ -188,7 +191,7 @@ namespace Sharp.Augeas
public int InsertNode(string matchPath, string label, int before = 0)
{
- return insert_node(_augeas, matchPath, label, before);
+ return insert_node(_augeas, matchPath, label, before);
}
@@ -219,16 +222,16 @@ namespace Sharp.Augeas
FreeString(raw);
return sb;
}
-
- #endregion
-
-
+
+ #endregion
+
+
///
/// Matches of the path expression PATH in AUG.
///
/// Augeas path.
///
- public string[] Match (string matchPath)
+ public string[] Match(string matchPath)
{
sbyte** result = null;
var count = match(_augeas, matchPath, &result);
@@ -248,42 +251,9 @@ namespace Sharp.Augeas
result[i] = Marshal.PtrToStringUTF8((IntPtr)list[i]);
Marshal.FreeCoTaskMem((IntPtr)list[i]);
}
-
+
return result;
}
-
-
-
- ///
- /// Given a , prints the Virtual Host tree.
- ///
- /// Apache configuration file.
- public void PrintVirtualHostTree(string apacheSitePath)
- {
- LoadFile(apacheSitePath);
- string virtualHostTree = $"/files{apacheSitePath}/VirtualHost/*";
- PrintTree(virtualHostTree);
- }
-
- ///
- /// Given a , gets a virtual host tree.
- ///
- /// Apache configuration file.
- ///
- public Dictionary GetVirtualHostTree(string apacheSitePath)
- {
- LoadFile(apacheSitePath);
- string virtualHostTree = $"/files{apacheSitePath}/VirtualHost/*";
- return GetTree(virtualHostTree);
- }
-
- void PrintVirtualHostProxyTree(string apacheSitePath)
- {
- LoadFile(apacheSitePath);
- string virtualHostProxyMatchPath = $"/files{apacheSitePath}/VirtualHost/Proxy/*";
- PrintTree(virtualHostProxyMatchPath);
- }
-
}
-}
+}
\ No newline at end of file
diff --git a/Sharp.Augeas/Platform/Linux/libclAugeas.so b/Sharp.Augeas/Platform/Linux/libclAugeas.so
index 6903728..e69de29 100644
Binary files a/Sharp.Augeas/Platform/Linux/libclAugeas.so and b/Sharp.Augeas/Platform/Linux/libclAugeas.so differ
diff --git a/Sharp.Augeas/Sharp.Augeas.csproj b/Sharp.Augeas/Sharp.Augeas.csproj
index ddd724c..56cc1ed 100644
--- a/Sharp.Augeas/Sharp.Augeas.csproj
+++ b/Sharp.Augeas/Sharp.Augeas.csproj
@@ -15,7 +15,7 @@
root\%(RecursiveDir)\%(Filename)%(Extension)
-
+
PreserveNewest
diff --git a/Sharp.Augeas/Tree/Argument.cs b/Sharp.Augeas/Tree/Argument.cs
new file mode 100644
index 0000000..e0eadea
--- /dev/null
+++ b/Sharp.Augeas/Tree/Argument.cs
@@ -0,0 +1,25 @@
+namespace Sharp.Augeas;
+
+public class Argument : Node
+{
+
+ public string Value;
+
+ public bool SetValue(string newValue)
+ {
+ Value = newValue;
+ return _augeas.SetNode(Path, newValue);
+ }
+
+ public Argument(Augeas augeas, string id, string path, string value) : base(augeas, path)
+ {
+ Id = id;
+ Path = path;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+ return Value;
+ }
+}
\ No newline at end of file
diff --git a/Sharp.Augeas/Tree/Directive.cs b/Sharp.Augeas/Tree/Directive.cs
new file mode 100644
index 0000000..3cb6f42
--- /dev/null
+++ b/Sharp.Augeas/Tree/Directive.cs
@@ -0,0 +1,74 @@
+using System.Text;
+
+namespace Sharp.Augeas;
+
+public class Directive : Node
+{
+ public string Value;
+ public List Arguments;
+ public bool HasArguments => Arguments.Count != 0;
+
+ ///
+ /// Sets a new value for the directive using string literals
+ /// The values are separated by spaces, the first value is the directive value,
+ /// the other values are values corresponding to the arguments.
+ ///
+ ///
+ public void Set(string newValue)
+ {
+ var splitted = newValue.Split(" ");
+
+ if (splitted.Length > 0)
+ {
+ SetValue(splitted[0]);
+ }
+
+ for (int i = 1; i < splitted.Length; i++)
+ {
+ var argumentIndex = i - 1;
+ Arguments[argumentIndex].SetValue(splitted[i]);
+ }
+ }
+
+ ///
+ /// Set the value of this directive.
+ /// Note: This doesn't write any changes to disk.
+ ///
+ /// New value.
+ ///
+ public bool SetValue(string newValue)
+ {
+ Value = newValue;
+ return _augeas.SetNode(Path, newValue);
+ }
+
+ public Directive(Augeas augeas, string id, string path, string value) : base(augeas, path)
+ {
+ Value = value;
+ Id = id;
+ Path = path;
+ Arguments = new List();
+ }
+
+ ///
+ /// Add a argument to this node.
+ ///
+ ///
+ public void AddArgument(Argument argument)
+ {
+ argument.Parent = this;
+ Arguments.Add(argument);
+ }
+
+ public override string ToString()
+ {
+ var sb = new StringBuilder($"{Value} ");
+
+ foreach (var arg in Arguments)
+ {
+ sb.Append($"{arg} ");
+ }
+
+ return sb.ToString().TrimEnd();
+ }
+}
\ No newline at end of file
diff --git a/Sharp.Augeas/Tree/Node.cs b/Sharp.Augeas/Tree/Node.cs
new file mode 100644
index 0000000..090115f
--- /dev/null
+++ b/Sharp.Augeas/Tree/Node.cs
@@ -0,0 +1,28 @@
+namespace Sharp.Augeas;
+
+public class Node
+{
+ public string Id;
+ public Node Parent;
+ public string Path;
+ protected readonly Augeas _augeas;
+
+ public Node(Augeas augeas, string path)
+ {
+ _augeas = augeas;
+ Parent = null;
+ Path = path;
+ }
+ public Node(Augeas augeas, Node parent, string path)
+ {
+ _augeas = augeas;
+ Parent = parent;
+ Path = path;
+ }
+
+ public bool Save()
+ {
+ return _augeas.Save();
+ }
+
+}
\ No newline at end of file
diff --git a/Sharp.Augeas/Tree/SuperNode.cs b/Sharp.Augeas/Tree/SuperNode.cs
new file mode 100644
index 0000000..fec60f4
--- /dev/null
+++ b/Sharp.Augeas/Tree/SuperNode.cs
@@ -0,0 +1,56 @@
+using System.Text;
+
+namespace Sharp.Augeas
+{
+ public class SuperNode : Node
+ {
+ public List Directives;
+ public List Arguments;
+ public List SuperNodes;
+
+ public SuperNode(Augeas augeas, string path, string id) : base(augeas, path)
+ {
+ Path = path;
+ Id = id;
+ Directives = new List();
+ Arguments = new List();
+ SuperNodes = new List();
+ }
+
+ public Directive GetDirective(string value)
+ {
+ return Directives.FirstOrDefault(d => d.Value == value, null);
+ }
+
+ public void AddArgument(Argument argument)
+ {
+ argument.Parent = this;
+ Arguments.Add(argument);
+ }
+
+ public void AddDirective(Directive directive)
+ {
+ directive.Parent = this;
+ Directives.Add(directive);
+ }
+
+ public void AddSuperNode(SuperNode superNode)
+ {
+ superNode.Parent = this;
+ SuperNodes.Add(superNode);
+ }
+
+ public override string ToString()
+ {
+ var sb = new StringBuilder($"{Id} ");
+
+ foreach (var arg in Arguments)
+ {
+ sb.Append($"{arg} ");
+ }
+
+ return sb.ToString().TrimEnd();;
+ }
+ }
+}
+
diff --git a/Sharp.Augeas/Tree/TreeExtensions.cs b/Sharp.Augeas/Tree/TreeExtensions.cs
new file mode 100644
index 0000000..6748d45
--- /dev/null
+++ b/Sharp.Augeas/Tree/TreeExtensions.cs
@@ -0,0 +1,119 @@
+using System.Text;
+
+namespace Sharp.Augeas;
+
+public static class TreeExtensions
+{
+ ///
+ /// Builds a typed tree with the
+ ///
+ ///
+ /// Super node name.
+ /// Augeas path.
+ ///
+ public static SuperNode GetTree(this Augeas augeas, string superNodeName, string augeasPath)
+ {
+ var basePath = augeasPath.Replace("*", "");
+ var tree = augeas.GetDictionaryTree(augeasPath);
+ Dictionary addedDirectives = new Dictionary();
+ Dictionary addedSuperNodes = new Dictionary();
+ addedSuperNodes.Add(superNodeName, new SuperNode(augeas, augeasPath, superNodeName));
+
+ foreach (var treeKey in tree.Keys)
+ {
+ var hierarchy = treeKey.Split('/');
+ var firstElement = hierarchy[0];
+ // Parent
+ if (hierarchy.Length <= 1)
+ {
+ var rFullPath = $"{basePath}{firstElement}";
+ if (firstElement.StartsWith("directive"))
+ {
+ Directive directive = new Directive(augeas, firstElement, rFullPath, tree[firstElement]);
+ directive.Parent = addedSuperNodes[superNodeName];
+ addedSuperNodes[superNodeName].AddDirective(directive);
+ addedDirectives.Add(treeKey, directive);
+ continue;
+ }
+ // If is argument
+ if (firstElement.StartsWith("arg"))
+ {
+ Argument argument = new Argument(augeas, firstElement, rFullPath, tree[firstElement]);
+ argument.Parent = addedSuperNodes[superNodeName];
+ addedSuperNodes[superNodeName].AddArgument(argument);
+ continue;
+ }
+ if (IsSuperNodeCandidate(firstElement) && !addedSuperNodes.ContainsKey(firstElement))
+ {
+ var superNode = new SuperNode(augeas, rFullPath, firstElement);
+ superNode.Parent = addedSuperNodes[superNodeName];
+ addedSuperNodes.Add(firstElement, superNode);
+ }
+ continue;
+ }
+ // handle children
+ for (var i = 1; i < hierarchy.Length; i++)
+ {
+ var childKey = hierarchy[i];
+ var parentPathBuilder = new StringBuilder();
+
+ for (int j = 0; j < i; j++) parentPathBuilder.Append($"{hierarchy[j]}/");
+
+ var parentPath = parentPathBuilder.ToString();
+ parentPath = parentPath.Trim('/');
+ var fullPath = $"{parentPath}/{childKey}";
+ var rFullPath = $"{basePath}{fullPath}";
+ var childValue = tree[fullPath];
+
+ if (IsSuperNodeCandidate(firstElement) && !addedSuperNodes.ContainsKey(firstElement))
+ {
+ var superNode = new SuperNode(augeas, rFullPath, firstElement);
+ superNode.Parent = addedSuperNodes[superNodeName];
+ addedSuperNodes.Add(firstElement, superNode);
+ }
+ if (childKey.StartsWith("directive"))
+ {
+ Directive directive = new Directive(augeas, childKey, rFullPath, childValue);
+ if (addedDirectives.ContainsKey(fullPath)) continue;
+ addedDirectives.Add(fullPath, directive);
+ if (addedSuperNodes.ContainsKey(parentPath))
+ addedSuperNodes[parentPath].AddDirective(directive);
+
+ continue;
+ }
+ if (childKey.StartsWith("arg"))
+ {
+ Argument argument = new Argument(augeas, childKey, rFullPath, childValue);
+
+ if (addedDirectives.ContainsKey(parentPath))
+ {
+ addedDirectives[parentPath].AddArgument(argument);
+ continue;
+ }
+
+ if (addedSuperNodes.ContainsKey(parentPath))
+ addedSuperNodes[parentPath].AddArgument(argument);
+ }
+ }
+ }
+
+ var superNodes = addedSuperNodes.Keys;
+
+ foreach (var key in superNodes)
+ {
+ if (key != superNodeName)
+ {
+ addedSuperNodes[superNodeName].AddSuperNode(addedSuperNodes[key]);
+ }
+ }
+
+ return addedSuperNodes[superNodeName];
+ }
+
+
+ private static bool IsSuperNodeCandidate(string key)
+ {
+ return !key.StartsWith("arg") && !key.StartsWith("directive");
+ }
+
+}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/ApacheConfigExtensions.cs b/Sharp.Augeas/VirtualHost/ApacheConfigExtensions.cs
deleted file mode 100644
index 76e6819..0000000
--- a/Sharp.Augeas/VirtualHost/ApacheConfigExtensions.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Sharp.Augeas;
-
-public static class ApacheConfigExtensions
-{
-
-}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/Argument.cs b/Sharp.Augeas/VirtualHost/Argument.cs
deleted file mode 100644
index 05af516..0000000
--- a/Sharp.Augeas/VirtualHost/Argument.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Sharp.Augeas;
-
-public class Argument : Node where T: Node
-{
- public new T Parent;
-
- public string Value;
-
- public Argument(T parent, string value)
- {
- Parent = parent;
- Children = null;
- Value = value;
- }
-
- public Argument()
- {
-
- }
-}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/Directive.cs b/Sharp.Augeas/VirtualHost/Directive.cs
deleted file mode 100644
index c97f8e7..0000000
--- a/Sharp.Augeas/VirtualHost/Directive.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Sharp.Augeas;
-
-public class Directive : Node
-{
- public string Value;
- public List Arguments;
-}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/Node.cs b/Sharp.Augeas/VirtualHost/Node.cs
deleted file mode 100644
index 3babfe9..0000000
--- a/Sharp.Augeas/VirtualHost/Node.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-namespace Sharp.Augeas;
-
-public class Node
-{
- public Node Parent;
- public List Children;
-
-
- public Node()
- {
- Parent = null;
- Children = new List();
- }
- public Node(Node parent)
- {
- Parent = parent;
- Children = new List();
- }
-
- public T[] GetChildren()
- {
- return Children
- .OfType()
- .ToArray();
- }
-
- public Node(Node parent, List children)
- {
- Parent = parent;
- Children = children;
- }
-
- public void AddChild(Node node)
- {
- Children.Add(node);
- }
-
- public void RemoveChild(Node child)
- {
- if (Children.Contains(child))
- {
- Children.Remove(child);
- }
- }
-
- public void RemoveAllChildren()
- {
- Children = new List();
- }
-}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/Proxy.cs b/Sharp.Augeas/VirtualHost/Proxy.cs
deleted file mode 100644
index 7d8f0aa..0000000
--- a/Sharp.Augeas/VirtualHost/Proxy.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Sharp.Augeas;
-
-public class Proxy : Node
-{
- public new VirtualHost Parent;
- public List> Directives;
- public List> Arguments;
-}
\ No newline at end of file
diff --git a/Sharp.Augeas/VirtualHost/VirtualHost.cs b/Sharp.Augeas/VirtualHost/VirtualHost.cs
deleted file mode 100644
index 538cf63..0000000
--- a/Sharp.Augeas/VirtualHost/VirtualHost.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Sharp.Augeas
-{
- public class VirtualHost : Node
- {
- public List> Directives;
- public List> Arguments;
- }
-}
-
diff --git a/Sharp.Augeas/VirtualHostTreeGenerator.cs b/Sharp.Augeas/VirtualHostTreeGenerator.cs
deleted file mode 100644
index 073129a..0000000
--- a/Sharp.Augeas/VirtualHostTreeGenerator.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace Sharp.Augeas;
-
-public static class VirtualHostTreeGenerator
-{
- public static VirtualHost Generate(Dictionary dic)
- {
- var keys = dic.Keys;
- var virtualHost = new VirtualHost();
- foreach (var key in keys)
- {
-
- }
-
- return virtualHost;
- }
-
- private static bool IsProxy(string key)
- {
- return key.Contains("f/VirtualHost/Proxy/");
- }
- private static bool IsVirtualHostArg(string key)
- {
- return key.Contains("f/VirtualHost/arg;");
- }
- private static bool IsProxyDirective(string key)
- {
- return key.Contains("f/VirtualHost/Proxy/directive");
- }
- private static bool IsVirtualHostDirective(string key)
- {
- return key.Contains("f/VirtualHost/directive");
- }
- private static bool IsDirectiveArg(string key)
- {
- return key.Contains("f/VirtualHost/directive");
- }
-
-}
\ No newline at end of file