#include <getopt.h>
#include <stdbool.h>
#include <ctype.h>
+#include <libgen.h>
#include "memory.h"
#include "augeas.h"
#include <locale.h>
+#define EXIT_TROUBLE 2
+
#define cleanup(_x) __attribute__((__cleanup__(_x)))
const char *progname;
" -e, --exact print only exact matches instead of the entire tree\n"
" starting at a match\n"
" -o, --only-value print only the values of tree nodes, but no path\n"
+" -q, --quiet do not print anything. Exit with zero status if a\n"
+" match was found\n"
" -r, --root ROOT use ROOT as the root of the filesystem\n"
" -I, --include DIR search DIR for modules; can be given mutiple times\n"
" -S, --nostdinc do not search the builtin default directories\n"
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
- exit(EXIT_FAILURE);
+ exit(EXIT_TROUBLE);
}
}
if (msg != NULL) {
fprintf(stderr, "%s\n", msg);
}
- exit(EXIT_FAILURE);
+ exit(EXIT_TROUBLE);
}
}
const char *msg, *line, *col;
aug_defvar(aug, "info", info);
+ free(info);
die(aug_ns_count(aug, "info") == 0, "file %s does not exist\n", file);
aug_defvar(aug, "error", "$info/error");
} else {
fprintf(stderr, "error reading %s: %s\n", file, msg);
}
- exit(EXIT_FAILURE);
+ exit(EXIT_TROUBLE);
}
/* We keep track of where we are in the tree when we are printing it by
}
/* Print the tree for file PATH (which must already start with /files), but
- * only the nodes matching MATCH */
-static void print(struct augeas *aug, const char *path, const char *match) {
+ * only the nodes matching MATCH.
+ *
+ * Return EXIT_SUCCESS if there was at least one match, and EXIT_FAILURE
+ * if there was none.
+ */
+static int print(struct augeas *aug, const char *path, const char *match) {
static const char *const match_var = "match";
- cleanup(freep) struct node *nodes = NULL;
+ struct node *nodes = NULL;
nodes = calloc(max_nodes, sizeof(struct node));
oom_when(nodes == NULL);
- aug_set(aug, "/augeas/context", path);
-
for (int i=0; i < max_nodes; i++) {
nodes[i].var = format("var%d", i);
}
aug_defvar(aug, nodes[0].var, prefix);
print_tree(aug, 0, prefix + strlen(path) + 1, nodes);
}
+ for (int i=0; i < max_nodes; i++) {
+ free(nodes[i].var);
+ }
+ free(nodes);
+
+ return (count == 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}
/* Look at the filename and try to guess based on the extension. The
size_t matches_len = 0;
const char *match = "*";
bool print_lens = false;
+ bool quiet = false;
+ int result = EXIT_SUCCESS;
struct option options[] = {
{ "help", 0, 0, 'h' },
{ "root", 1, 0, 'r' },
{ "print-lens", 0, 0, 'L' },
{ "exact", 0, 0, 'e' },
+ { "quiet", 0, 0, 'q' },
{ 0, 0, 0, 0}
};
unsigned int flags = AUG_NO_LOAD|AUG_NO_ERR_CLOSE;
progname = basename(argv[0]);
setlocale(LC_ALL, "");
- while ((opt = getopt_long(argc, argv, "ahI:l:m:oSr:eL", options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "ahI:l:m:oSr:eLq", options, NULL)) != -1) {
switch(opt) {
case 'I':
argz_add(&loadpath, &loadpath_len, optarg);
case 'e':
print_exact = true;
break;
+ case 'q':
+ quiet = true;
+ break;
default:
fprintf(stderr, "Try '%s --help' for more information.\n",
progname);
- exit(EXIT_FAILURE);
+ exit(EXIT_TROUBLE);
break;
}
}
fprintf(stderr, "Expected an input file\n");
fprintf(stderr, "Try '%s --help' for more information.\n",
progname);
- exit(EXIT_FAILURE);
+ exit(EXIT_TROUBLE);
}
const char *file = argv[optind];
check_load_error(aug, file);
char *path = format("/files%s", file);
+ aug_set(aug, "/augeas/context", path);
+
if (matches_len > 0) {
argz_stringify(matches, matches_len, '|');
match = matches;
}
- print(aug, path, match);
+ if (quiet) {
+ int n = aug_match(aug, match, NULL);
+ check_error(aug);
+ result = (n == 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+ } else {
+ result = print(aug, path, match);
+ }
+ free(path);
+
+ return result;
}
/*