7 #if defined(WITH_AUGEAS) && defined(HAVE_AUGEAS_H)
17 #define _RPMIOB_INTERNAL
23 #define _RPMAUG_INTERNAL
45 #if defined(WITH_AUGEAS)
46 augeas * I = (augeas *) aug->I;
52 aug->root =
_free(aug->root);
53 aug->loadpath =
_free(aug->loadpath);
66 if (_rpmaugPool == NULL) {
67 _rpmaugPool =
rpmioNewPool(
"aug",
sizeof(*aug), -1, _rpmaug_debug,
75 static const char _root[] =
"/";
82 #if defined(REFERENCE)
84 static
void usage(
void)
86 fprintf(stderr,
"Usage: %s [OPTIONS] [COMMAND]\n",
progname);
87 fprintf(stderr,
"Load the Augeas tree and modify it. If no COMMAND is given, run interactively\n");
88 fprintf(stderr,
"Run '%s help' to get a list of possible commands.\n",
90 fprintf(stderr,
"\nOptions:\n\n");
91 fprintf(stderr,
" -c, --typecheck typecheck lenses\n");
92 fprintf(stderr,
" -b, --backup preserve originals of modified files with\n"
93 " extension '.augsave'\n");
94 fprintf(stderr,
" -n, --new save changes in files with extension '.augnew',\n"
95 " leave original unchanged\n");
96 fprintf(stderr,
" -r, --root ROOT use ROOT as the root of the filesystem\n");
97 fprintf(stderr,
" -I, --include DIR search DIR for modules; can be given mutiple times\n");
98 fprintf(stderr,
" --nostdinc do not search the builtin default directories for modules\n");
99 fprintf(stderr,
" --noload do not load any files into the tree on startup\n");
100 fprintf(stderr,
" --noautoload do not autoload modules from the search path\n");
110 #if defined(WITH_AUGEAS)
112 {
"typecheck",
'c', POPT_BIT_SET, &
_rpmaugFlags, AUG_TYPE_CHECK,
113 N_(
"Type check lenses"), NULL },
114 {
"backup",
'b',POPT_BIT_SET, &
_rpmaugFlags, AUG_SAVE_BACKUP,
115 N_(
"Backup modified files with suffix '.augsave'"), NULL },
116 {
"new",
'n', POPT_BIT_SET, &
_rpmaugFlags, AUG_SAVE_NEWFILE,
117 N_(
"Save modified files with suffix '.augnew'"), NULL },
119 N_(
"Use ROOT as the root of the filesystem"),
N_(
"ROOT") },
121 N_(
"Search DIR for modules (may be used more than once)"),
N_(
"DIR") },
122 {
"nostdinc",
'\0', POPT_BIT_SET, &
_rpmaugFlags, AUG_NO_STDINC,
123 N_(
"Do not search default modules path"), NULL },
124 {
"noload",
'\0', POPT_BIT_SET, &
_rpmaugFlags, AUG_NO_LOAD,
125 N_(
"Do not load files into tree on startup"), NULL },
126 {
"noautoload",
'\0', POPT_BIT_SET, &
_rpmaugFlags, AUG_NO_MODL_AUTOLOAD,
127 N_(
"Do not autoload modules from the search path"), NULL },
136 if (root == NULL || *root ==
'\0')
138 if (root == NULL || *root ==
'\0')
140 if (loadpath == NULL)
143 aug->loadpath =
xstrdup(loadpath);
145 #if defined(WITH_AUGEAS)
146 aug->I = (
void *) aug_init(aug->root, aug->loadpath, aug->flags);
147 assert(aug->I != NULL);
155 static rpmaug rpmaugI(
void)
159 if (_rpmaugI == NULL)
160 _rpmaugI =
rpmaugNew(_rpmaugRoot, _rpmaugLoadpath, _rpmaugFlags);
170 if (aug == NULL) aug = rpmaugI();
171 I = (augeas *) aug->I;
172 rc = aug_defvar(I, name, expr);
174 if (_rpmaug_debug < 0)
175 fprintf(stderr,
"<-- %s(%p,\"%s\",\"%s\") rc %d\n", __FUNCTION__, aug, name, expr, rc);
180 const char * value,
int * created)
185 if (aug == NULL) aug = rpmaugI();
186 I = (augeas *) aug->I;
187 rc = aug_defnode(I, name, expr, value, created);
189 if (_rpmaug_debug < 0)
190 fprintf(stderr,
"<-- %s(%p,\"%s\",\"%s\",\"%s\",%p) rc %d *created %d\n", __FUNCTION__, aug, name, expr, value, created, rc, (created ? *created : 0));
199 if (aug == NULL) aug = rpmaugI();
200 I = (augeas *) aug->I;
201 rc = aug_get(I, path, value);
203 if (_rpmaug_debug < 0)
204 fprintf(stderr,
"<-- %s(%p,\"%s\",%p) rc %d *value \"%s\"\n", __FUNCTION__, aug, path, value, rc, (value ? *value : NULL));
213 if (aug == NULL) aug = rpmaugI();
214 I = (augeas *) aug->I;
215 rc = aug_set(I, path, value);
217 if (_rpmaug_debug < 0)
218 fprintf(stderr,
"<-- %s(%p,\"%s\",\"%s\") rc %d\n", __FUNCTION__, aug, path, value, rc);
227 if (aug == NULL) aug = rpmaugI();
228 I = (augeas *) aug->I;
229 rc = aug_insert(I, path, label, before);
231 if (_rpmaug_debug < 0)
232 fprintf(stderr,
"<-- %s(%p,\"%s\",\"%s\",%d) rc %d\n", __FUNCTION__, aug, path, label, before, rc);
241 if (aug == NULL) aug = rpmaugI();
242 I = (augeas *) aug->I;
243 rc = aug_rm(I, path);
245 if (_rpmaug_debug < 0)
246 fprintf(stderr,
"<-- %s(%p,\"%s\") rc %d\n", __FUNCTION__, aug, path, rc);
255 if (aug == NULL) aug = rpmaugI();
256 I = (augeas *) aug->I;
257 rc = aug_mv(I, src, dst);
259 if (_rpmaug_debug < 0)
260 fprintf(stderr,
"<-- %s(%p,\"%s\",\"%s\") rc %d\n", __FUNCTION__, aug, src, dst, rc);
269 if (aug == NULL) aug = rpmaugI();
270 I = (augeas *) aug->I;
271 rc = aug_match(I, path, matches);
273 if (_rpmaug_debug < 0)
274 fprintf(stderr,
"<-- %s(%p,\"%s\",%p) rc %d *matches %p\n", __FUNCTION__, aug, path, matches, rc, (matches ? *matches : NULL));
283 if (aug == NULL) aug = rpmaugI();
284 I = (augeas *) aug->I;
287 if (_rpmaug_debug < 0)
288 fprintf(stderr,
"<-- %s(%p) rc %d\n", __FUNCTION__, aug, rc);
297 if (aug == NULL) aug = rpmaugI();
298 I = (augeas *) aug->I;
301 if (_rpmaug_debug < 0)
302 fprintf(stderr,
"<-- %s(%p) rc %d\n", __FUNCTION__, aug, rc);
311 if (aug == NULL) aug = rpmaugI();
312 I = (augeas *) aug->I;
313 if (out == NULL) out = stderr;
314 rc = aug_print(I, out, path);
317 if (_rpmaug_debug < 0)
318 fprintf(stderr,
"<-- %s(%p, %p, \"%s\") rc %d\n", __FUNCTION__, aug, out, path, rc);
324 #if defined(WITH_AUGEAS)
332 if (nw > -1 && (
size_t)nw < nb)
342 if (aug == NULL) aug = rpmaugI();
354 #define DATADIR "/usr/share"
358 #define AUGEAS_LENS_DIR DATADIR "/augeas/lenses"
361 #define AUGEAS_LENS_DIST_DIR DATADIR "/augeas/lenses/dist"
366 #define PATH_SEP_CHAR ':'
373 char *e = path + strlen(path) - 1;
374 while (e >= path && (*e == sep ||
xisspace(*e)))
389 augeas * I = (augeas *) aug->I;
391 if (aug_error(I) != AUG_NOERROR) {
392 const char *
minor = aug_error_minor_message(I);
393 const char *details = aug_error_details(I);
395 fprintf(stderr,
"error: %s\n", aug_error_message(I));
397 fprintf(stderr,
"error: %s\n", minor);
399 fprintf(stderr,
"error: %s\n", details);
409 if (path[strlen(path)-1] ==
SEP)
410 r = asprintf(&q,
"%s*", path);
412 r = asprintf(&q,
"%s/*", path);
448 for (i = 0; i < cnt; i++) {
449 const char *basnam = strrchr(paths[i],
SEP);
454 basnam = (basnam == NULL) ? paths[i] : basnam + 1;
457 rpmaugFprintf(NULL,
"%s%s= %s\n", basnam, dir ?
"/ " :
" ", val);
458 paths[
i] =
_free(paths[i]);
461 paths =
_free(paths);
469 int filter = (av[1] != NULL) && (strlen(av[1]) > 0);
471 char **matches = NULL;
487 for (i = 0; i < cnt; i++) {
494 if (!strcmp(av[1], val))
501 for (i = 0; i < cnt; i++)
502 matches[i] =
_free(matches[i]);
503 matches =
_free(matches);
534 const char *val = av[1];
545 const char *
name = av[0];
546 const char *path = (av[1] && *av[1] ?
cleanpath(av[1]) : NULL);
557 const char *
name = av[0];
559 const char *value = av[2];
564 if (value != NULL && value[0] ==
'\0')
593 else if (val == NULL)
616 r =
rpmaugMatch(NULL,
"/augeas/events/saved", NULL);
632 r =
rpmaugMatch(NULL,
"/augeas/events/saved", NULL);
643 const char *label = av[0];
644 const char *where = av[1];
649 if (!strcmp(where,
"after"))
651 else if (!strcmp(where,
"before"))
654 rpmaugFprintf(NULL,
"The <WHERE> argument must be either 'before' or 'after'.");
667 const struct poptOption * c;
672 c->longName, (c->argDescrip ? c->argDescrip :
""), c->descrip);
675 rpmaugFprintf(NULL,
" AUGEAS_ROOT\n the file system root, defaults to '/'\n\n");
676 rpmaugFprintf(NULL,
" AUGEAS_LENS_LIB\n colon separated list of directories with lenses,\n\
681 #define ARGMINMAX(_min, _max) (int)(((_min) << 8) | ((_max) & 0xff))
685 N_(
"List the direct children of PATH"),
N_(
"<PATH>")
688 N_(
"Find all paths that match the path expression PATH. If VALUE is given,\n"
689 " only the matching paths whose value equals VALUE are printed"),
690 N_(
"<PATH> [<VALUE>]")
693 N_(
"Delete PATH and all its children from the tree"),
N_(
"<PATH>")
696 N_(
"Move node SRC to DST. SRC must match exactly one node in the tree.\n"
697 " DST must either match exactly one node in the tree, or may not\n"
698 " exist yet. If DST exists already, it and all its descendants are\n"
699 " deleted. If DST does not exist yet, it and all its missing \n"
700 " ancestors are created."),
704 N_(
"Associate VALUE with PATH. If PATH is not in the tree yet,\n"
705 " it and all its ancestors will be created. These new tree entries\n"
706 " will appear last amongst their siblings"),
710 N_(
"Set the value for PATH to NULL. If PATH is not in the tree yet,\n"
711 " it and all its ancestors will be created. These new tree entries\n"
712 " will appear last amongst their siblings"),
716 N_(
"Print the value associated with PATH"),
N_(
"<PATH>")
719 N_(
"Print entries in the tree. If PATH is given, printing starts there,\n"
720 " otherwise the whole tree is printed"),
724 N_(
"Insert a new node with label LABEL right before or after PATH into\n"
725 " the tree. WHERE must be either 'before' or 'after'."),
726 N_(
"<LABEL> <WHERE> <PATH>")
729 N_(
"Save all pending changes to disk. For now, files are not overwritten.\n"
730 " Instead, new files with extension .augnew are created"),
734 N_(
"Load files accordig to the transforms in /augeas/load."), NULL
737 N_(
"Define the variable NAME to the result of evalutating EXPR. The\n"
738 " variable can be used in path expressions as $NAME. Note that EXPR\n"
739 " is evaluated when the variable is defined, not when it is used."),
743 N_(
"Define the variable NAME to the result of evalutating EXPR, which\n"
744 " must be a nodeset. If no node matching EXPR exists yet, one\n"
745 " is created and NAME will refer to it. If VALUE is given, this\n"
746 " is the same as 'set EXPR VALUE'; if VALUE is not given, the\n"
747 " node is created as if with 'clear EXPR' would and NAME refers\n"
749 N_(
"<NAME> <EXPR> [<VALUE>]")
752 N_(
"Exit the program"), NULL
755 N_(
"Exit the program"), NULL
758 N_(
"Print this help text"), NULL
760 { NULL,
'\0', 0, NULL,
ARGMINMAX(0, 0), NULL, NULL }
770 if (aug == NULL) aug = rpmaugI();
772 if (aug == NULL)
return rc;
779 const struct poptOption * c;
780 int (*handler) (
int ac,
char * av[]);
786 if (!(P->
av && P->
ac > 0 && P->
av[0] != NULL && strlen(P->
av[0]) > 0))
789 for (c = _rpmaugCommandTable; c->longName; c++) {
790 if (strcmp(P->
av[0], c->longName))
792 handler = (int (*)(int,
char**)) c->arg;
793 minargs = (c->val >> 8) & 0xff;
794 maxargs = (c->val ) & 0xff;
797 if (c->longName == NULL) {
801 if ((P->
ac - 1) < minargs) {
802 rpmaugFprintf(NULL,
"Not enough arguments for %s\n", c->longName);
805 if ((P->
ac - 1) > maxargs) {
806 rpmaugFprintf(NULL,
"Too many arguments for %s\n", c->longName);
809 if ((xx = (*handler)(P->
ac-1, (
char **)P->
av+1)) < 0) {
811 if (!strcmp(c->longName,
"quit") || !strcmp(c->longName,
"exit"))
824 if (resultp && iob->blen > 0)
static int cmd_help(int ac, char *av[])
int rpmaugRm(rpmaug aug, const char *path)
Remove node and associated sub-tree.
const char * _rpmaugLoadpath
static int cmd_ls(int ac, char *av[])
static int cmd_quit(int ac, char *av[])
static char * ls_pattern(const char *path)
char * xstrdup(const char *str)
static int cmd_load(int ac, char *av[])
static int cmd_set(int ac, char *av[])
int rpmaugLoad(rpmaug aug)
Load files/lenses from disk.
static int child_count(const char *path)
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static int cmd_mv(int ac, char *av[])
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
rpmaug rpmaugLink(rpmaug aug)
Reference a augeas wrapper instance.
rpmRC rpmaugRun(rpmaug aug, const char *str, const char **resultp)
Run augeas commands from a buffer.
static int cmd_clear(int ac, char *av[])
struct poptOption rpmaugPoptTable[]
Popt option table for options to configure Augeas augtool.
unsigned int _rpmaugFlags
const char ** _rpmaugLoadargv
static int cmd_defnode(int ac, char *av[])
static int cmd_print(int ac, char *av[])
Yet Another syslog(3) API clone.
static const char _root[]
static int cmd_defvar(int ac, char *av[])
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
static char * cleanstr(char *path, const char sep)
int rpmaugDefvar(rpmaug aug, const char *name, const char *expr)
Define an augeas variable.
static int xisspace(int c)
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
int rpmaugMv(rpmaug aug, const char *src, const char *dst)
Move src node to dst node.
int rpmaugSet(rpmaug aug, const char *path, const char *value)
Set the value associated with a path.
static char * cleanpath(char *path)
const struct poptOption _rpmaugCommandTable[]
int rpmaugDefnode(rpmaug aug, const char *name, const char *expr, const char *value, int *created)
Define an augeas node.
static int cmd_get(int ac, char *av[])
static void err_check(void)
int rpmaugPrint(rpmaug aug, FILE *out, const char *path)
Print node paths that match an expression.
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
int rpmaugMatch(rpmaug aug, const char *path, char ***matches)
Return path(s) in tree that match an expression.
const char const bson int mongo_write_concern int flags
static rpmaug rpmaugGetPool(rpmioPool pool)
static int cmd_match(int ac, char *av[])
enum rpmRC_e rpmRC
RPM return codes.
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
#define ARGMINMAX(_min, _max)
const char const bson const bson bson * out
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
int rpmaugGet(rpmaug aug, const char *path, const char **value)
Get the value associated with a path.
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
int rpmaugSave(rpmaug aug)
Save changed files to disk, appending .augnew or .augsave as requested.
static const char _loadpath[]
static int cmd_rm(int ac, char *av[])
static int cmd_save(int ac, char *av[])
rpmaug rpmaugNew(const char *root, const char *loadpath, unsigned int flags)
Create and load a augeas wrapper.
const char const char * pattern
int rpmaugInsert(rpmaug aug, const char *path, const char *label, int before)
Insert new sibling node before/after a given node.
static int cmd_ins(int ac, char *av[])
static void rpmaugFini(void *_aug)
rpmRC rpmioParse(rpmioP *Pptr, const char *str)
Parse next command out of a string incrementally.
__attribute__((visibility("hidden"))) int mayAddToFilesAwaitingFiletriggers(const char *rootDir
void rpmaugFprintf(rpmaug aug, const char *fmt,...)
Append augeas output to an iob.