diff --git a/CodeLiturgy.Augeas/AugFlags.cs b/CodeLiturgy.Augeas/AugFlags.cs new file mode 100644 index 0000000..4256b1a --- /dev/null +++ b/CodeLiturgy.Augeas/AugFlags.cs @@ -0,0 +1,44 @@ +namespace CodeLiturgy.Augeas; + +public static class AugFlags +{ + public static int NONE = 0; + /** + * Keep the original file with a .augsave extension + */ + public static int SAVE_BACKUP = (1 << 0); + + /** + * Save changes into a file with extension .augnew, and do not overwrite the + * original file. Takes precedence over AUG_SAVE_BACKUP + */ + public static int SAVE_NEWFILE = (1 << 1); + + /** + * Typecheck lenses; since it can be very expensive it is not done by + * default + */ + public static int TYPE_CHECK = (1 << 2); + + /** + * Do not use the builtin load path for modules + */ + public static int NO_STDINC = (1 << 3); + + /** + * Make save a no-op process, just record what would have changed + */ + public static int SAVE_NOOP = (1 << 4); + + /** + * Do not load the tree from AUG_INIT + */ + public static int NO_LOAD = (1 << 5); + + public static int NO_MODL_AUTOLOAD = (1 << 6); + + /** + * Enable span on load + */ + public static int AUG_ENABLE_SPAN = (1 << 7); +} \ No newline at end of file diff --git a/CodeLiturgy.Augeas/Augeas.cs b/CodeLiturgy.Augeas/Augeas.cs new file mode 100644 index 0000000..262ae7f --- /dev/null +++ b/CodeLiturgy.Augeas/Augeas.cs @@ -0,0 +1,113 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using CodeLiturgy.Augeas.Test; +using static CodeLiturgy.Augeas.AugeasExtern; +using static CodeLiturgy.Augeas.AugFlags; + +namespace CodeLiturgy.Augeas +{ + /// + /// Augeas Core containing the settings of this instance. + /// We can have multiple augeas cores during the execution. + /// + public unsafe partial class Augeas + { + private readonly IntPtr _augeas; + + /// + /// Augeas Core Destructor + /// + ~Augeas() + { + // Effectively free the pointer + close_aug(_augeas); + } + + /// + /// Augeas Core constructor + /// + /// Augeas core instance settings + public Augeas(AugSettings augSettings) + { + _augeas = init_aug(augSettings, NO_STDINC | NO_LOAD); + } + + /// + /// Prints a preview of the desired segment in + /// + /// Augeas path to filter out the configuration + /// The actual configuration file path + public void PrintPreview(string matchPath) + { + print_preview(_augeas, matchPath); + } + + /// + /// Finalize the augeas instance. + /// + public void Close() + { + close_aug(_augeas); + } + + /// + /// Finalize the augeas instance. + /// + public void LoadFile(string configurationFilePath) + { + load_file(_augeas, configurationFilePath); + } + + /// + /// Prints the Aug Tree of a segment + /// + /// + /// + public void PrintAugTree(string matchPath) + { + print_tree(_augeas, matchPath); + } + + + /// + /// Returns the tree given the augeas configuration path. + /// + /// configuration path. + /// Dictionary with the Tree + public Dictionary GetTree(string matchPath) + { + var result = new Dictionary(); + var raw = get_tree(_augeas, matchPath); + string sb = Marshal.PtrToStringAnsi((IntPtr)raw); + if (sb == null) return result; + free_str(raw); + var lines = sb.Split(";ENDL;"); + foreach (var line in lines) + { + var pair = line.Split(";VAL;"); + if (pair.Length == 2) + { + result.Add(pair[0].Remove(0, 3), pair[1]); + } + } + + return result; + } + + + + public static void Benchmark(Action act, int iterations) + { + GC.Collect(); + act.Invoke(); // run once outside of loop to avoid initialization costs + Stopwatch sw = Stopwatch.StartNew(); + for (int i = 0; i < iterations; i++) + { + act.Invoke(); + } + sw.Stop(); + Console.WriteLine((sw.ElapsedMilliseconds / iterations).ToString()); + } + } +} diff --git a/CodeLiturgy.Augeas/AugeasExtern.cs b/CodeLiturgy.Augeas/AugeasExtern.cs index 647ce4b..4c37b61 100644 --- a/CodeLiturgy.Augeas/AugeasExtern.cs +++ b/CodeLiturgy.Augeas/AugeasExtern.cs @@ -1,6 +1,7 @@ using System.Numerics; using System.Runtime.InteropServices; using System.Security; +using System.Text; using CodeLiturgy.Augeas.Test; namespace CodeLiturgy.Augeas @@ -11,19 +12,20 @@ namespace CodeLiturgy.Augeas /// /// Used by DllImport to load the native library /// - public const string NativeLibName = "clAugeas"; + private const string _libName = "clAugeas"; /// Test calling - [DllImport(NativeLibName)] - public static extern void printPreview( AugSettings settings, - [MarshalAs(UnmanagedType.LPStr)] string matchPath, - [MarshalAs(UnmanagedType.LPStr)] string filePath); + [DllImport(_libName)] public static extern void print_preview(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath); + [DllImport(_libName)] public static extern void print_tree(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath); + [DllImport(_libName)] public static extern char* get_tree(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath); + [DllImport(_libName)] public static extern void defNode( AugSettings settings, [MarshalAs(UnmanagedType.LPStr)] string matchPath); + [DllImport(_libName)] public static extern void load_file(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string filePath); + [DllImport(_libName)] public static extern IntPtr init_aug( AugSettings settings, int flags); + [DllImport(_libName)] public static extern void close_aug (IntPtr aug); + [DllImport(_libName)] public static extern void free_str (char* str); - /// Test calling - [DllImport(NativeLibName)] - public static extern void printAugTree( AugSettings settings, - [MarshalAs(UnmanagedType.LPStr)] string matchPath, - [MarshalAs(UnmanagedType.LPStr)] string filePath); + + } } diff --git a/CodeLiturgy.Augeas/AugeasLib.cs b/CodeLiturgy.Augeas/AugeasLib.cs deleted file mode 100644 index de3b102..0000000 --- a/CodeLiturgy.Augeas/AugeasLib.cs +++ /dev/null @@ -1,22 +0,0 @@ -using CodeLiturgy.Augeas.Test; -using static CodeLiturgy.Augeas.AugeasExtern; - -namespace CodeLiturgy.Augeas -{ - public class AugeasLib - { - public static void PrintPreview(AugSettings settings, - string matchPath, - string filePath) - { - printPreview(settings, matchPath, filePath); - } - - /// Test calling - public static void PrintAugTree(AugSettings settings, string matchPath, - string filePath) - { - printAugTree(settings, matchPath, filePath); - } - } -} diff --git a/CodeLiturgy.Augeas/Program.cs b/CodeLiturgy.Augeas/Program.cs index 6a3ac2e..aa893ca 100644 --- a/CodeLiturgy.Augeas/Program.cs +++ b/CodeLiturgy.Augeas/Program.cs @@ -1,18 +1,24 @@ -using CodeLiturgy.Augeas.Test; -using static CodeLiturgy.Augeas.AugeasLib; +using CodeLiturgy.Augeas; +using CodeLiturgy.Augeas.Test; var path = Environment.CurrentDirectory; var root = $"{path}/root/"; AugSettings augSettings = new AugSettings(root, "/opt/homebrew/share/augeas/lenses/dist"); +var augeas = new Augeas(augSettings); // Calling extern functions string clSiteMatchPath = "/files/etc/apache2/sites-available/00-ci.codeliturgy.com.conf/VirtualHost"; string clSiteFilepath = "/etc/apache2/sites-available/00-ci.codeliturgy.com.conf"; -PrintAugTree(augSettings, clSiteMatchPath , clSiteFilepath); +//AugeasCore.Benchmark( () => augeasCore.PrintAugTree(clSiteMatchPath , clSiteFilepath), 10); +//AugeasCore.Benchmark( () => augeasCore.PrintPreview(clSiteMatchPath , clSiteFilepath), 10); + +augeas.LoadFile(clSiteFilepath); + +augeas.PrintAugTree(clSiteMatchPath); +var tree = augeas.GetTree(clSiteMatchPath); + -//PrintPreview(augSettings, clSiteMatchPath, clSiteFilepath); -//printPreview(augSettings, "/files/etc/apache2/sites-enabled/*", "/etc/apache2/sites-enabled"); \ No newline at end of file diff --git a/CodeLiturgy.Augeas/copyLibrary.sh b/CodeLiturgy.Augeas/copyLibrary.sh index 8ed5666..cf63408 100755 --- a/CodeLiturgy.Augeas/copyLibrary.sh +++ b/CodeLiturgy.Augeas/copyLibrary.sh @@ -1,13 +1,19 @@ #!/bin/bash -# Given the compiled library "claugeaslib" we need to copy it to the folder where the .NET -# executables are. - -# Intructions: -# 1. Set the $CLAUG_LIB_PATH to the PATH where the claugeas library is located before running this project -# 2- Run this shell script - +LIB_FILE=libclAugeas.dylib SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) DESTIN=$SCRIPT_DIR/bin/Debug/net6.0 -BINARY=$CLAUG_LIB_PATH/libclAugeas.dylib -cp -f $BINARY $DESTIN \ No newline at end of file + +# Set the $CLAUG_LIB_PATH to the PATH where the claugeas library is located before running this script + +if [[ -z "${CLAUG_LIB_PATH}" ]]; then + echo "set the CLAUG_LIB_PATH in the ${LIB_FILE} location." + return +fi + +BINARY=$CLAUG_LIB_PATH/$LIB_FILE + +if [ -e "$DESTIN/$LIB_FILE" ]; then + rm -fv $DESTIN/$LIB_FILE +fi +cp -v $BINARY $DESTIN \ No newline at end of file