Imported Upstream version 1.8.0
[platform/upstream/augeas.git] / src / augrun.c
index 15b1984..5ddc5ea 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <ctype.h>
 #include <libxml/tree.h>
+#include <argz.h>
 
 /*
  * Command handling infrastructure
@@ -935,6 +936,63 @@ static const struct command_def cmd_print_def = {
     .help = "Print entries in the tree.  If PATH is given, printing starts there,\n otherwise the whole tree is printed"
 };
 
+static void cmd_source(struct command *cmd) {
+    const char *path = arg_value(cmd, "path");
+    char *file_path = NULL;
+
+    aug_source(cmd->aug, path, &file_path);
+    ERR_RET(cmd);
+    if (file_path != NULL) {
+        fprintf(cmd->out, "%s\n", file_path);
+    }
+    free(file_path);
+}
+
+static const struct command_opt_def cmd_source_opts[] = {
+    { .type = CMD_PATH, .name = "path", .optional = false,
+      .help = "path to a single node" },
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_source_def = {
+    .name = "source",
+    .opts = cmd_source_opts,
+    .handler = cmd_source,
+    .synopsis = "print the file to which a node belongs",
+    .help = "Print the file to which the node for PATH belongs. PATH must match\n a single node coming from some file. In particular, that means\n it must be underneath /files."
+};
+
+static void cmd_context(struct command *cmd) {
+    const char *path = arg_value(cmd, "path");
+
+    if (path == NULL) {
+        aug_get(cmd->aug, "/augeas/context", &path);
+        ERR_RET(cmd);
+        if (path == NULL) {
+            fprintf(cmd->out, "/\n");
+        } else {
+            fprintf(cmd->out, "%s\n", path);
+        }
+    } else {
+        aug_set(cmd->aug, "/augeas/context", path);
+        ERR_RET(cmd);
+    }
+}
+
+static const struct command_opt_def cmd_context_opts[] = {
+    { .type = CMD_PATH, .name = "path", .optional = true,
+      .help = "new context for relative paths" },
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_context_def = {
+    .name = "context",
+    .opts = cmd_context_opts,
+    .handler = cmd_context,
+    .synopsis = "change how relative paths are interpreted",
+    .help = "Relative paths are interpreted relative to a context path which\n is stored in /augeas/context.\n\n When no PATH is given, this command prints the current context path\n and is equivalent to 'get /augeas/context'\n\n When PATH is given, this command changes that context, and has a\n similar effect to 'cd' in a shell and and is the same as running\n the command 'set /augeas/context PATH'."
+};
+
 static void cmd_dump_xml(struct command *cmd) {
     const char *path = arg_value(cmd, "path");
     xmlNodePtr xmldoc;
@@ -1090,6 +1148,63 @@ static const struct command_def cmd_load_def = {
     "is an  error if one file\n can be processed by multiple transforms."
 };
 
+static void cmd_info(struct command *cmd) {
+    const char *v;
+    int n;
+
+    aug_get(cmd->aug, "/augeas/version", &v);
+    ERR_RET(cmd);
+    if (v != NULL) {
+        fprintf(cmd->out, "version = %s\n", v);
+    }
+
+    aug_get(cmd->aug, "/augeas/root", &v);
+    ERR_RET(cmd);
+    if (v != NULL) {
+        fprintf(cmd->out, "root = %s\n", v);
+    }
+
+    fprintf(cmd->out, "loadpath = ");
+    for (char *entry = cmd->aug->modpathz;
+         entry != NULL;
+         entry = argz_next(cmd->aug->modpathz, cmd->aug->nmodpath, entry)) {
+        if (entry != cmd->aug->modpathz) {
+            fprintf(cmd->out, ":");
+        }
+        fprintf(cmd->out, "%s", entry);
+    }
+    fprintf(cmd->out, "\n");
+
+    aug_get(cmd->aug, "/augeas/context", &v);
+    ERR_RET(cmd);
+    if (v == NULL) {
+        v = "/";
+    }
+    fprintf(cmd->out, "context = %s\n", v);
+
+    n = aug_match(cmd->aug, "/augeas/files//path", NULL);
+    fprintf(cmd->out, "num_files = %d\n", n);
+}
+
+static const struct command_opt_def cmd_info_opts[] = {
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_info_def = {
+    .name = "info",
+    .opts = cmd_info_opts,
+    .handler = cmd_info,
+    .synopsis = "print runtime information",
+    .help = "Print information about Augeas. The output contains:\n"
+            "    version   : the version number from /augeas/version\n"
+            "    root      : what Augeas considers the filesystem root\n"
+            "                from /augeas/root\n"
+            "    loadpath  : the paths from which Augeas loads modules\n"
+            "    context   : the context path (see context command)\n"
+            "    num_files : the number of files currently loaded (based on\n"
+            "                the number of /augeas/files//path nodes)"
+};
+
 static void cmd_ins(struct command *cmd) {
     const char *label = arg_value(cmd, "label");
     const char *where = arg_value(cmd, "where");
@@ -1316,14 +1431,25 @@ static const struct command_def cmd_errors_def = {
 static const struct command_grp_def cmd_grp_admin_def = {
     .name = "Admin",
     .commands = {
-        &cmd_help_def,
+        &cmd_context_def,
         &cmd_load_def,
-        &cmd_quit_def,
-        &cmd_retrieve_def,
         &cmd_save_def,
-        &cmd_store_def,
         &cmd_transform_def,
         &cmd_load_file_def,
+        &cmd_retrieve_def,
+        &cmd_store_def,
+        &cmd_quit_def,
+        &cmd_def_last
+    }
+};
+
+static const struct command_grp_def cmd_grp_info_def = {
+    .name = "Informational",
+    .commands = {
+        &cmd_errors_def,
+        &cmd_info_def,
+        &cmd_help_def,
+        &cmd_source_def,
         &cmd_def_last
     }
 };
@@ -1337,7 +1463,6 @@ static const struct command_grp_def cmd_grp_read_def = {
         &cmd_ls_def,
         &cmd_match_def,
         &cmd_print_def,
-        &cmd_errors_def,
         &cmd_span_def,
         &cmd_def_last
     }
@@ -1374,6 +1499,7 @@ static const struct command_grp_def cmd_grp_pathx_def = {
 
 static const struct command_grp_def const *cmd_groups[] = {
     &cmd_grp_admin_def,
+    &cmd_grp_info_def,
     &cmd_grp_read_def,
     &cmd_grp_write_def,
     &cmd_grp_pathx_def,