2021-04-14 18:20:10

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 1/3] nfs-utils: Enable the retrieval of raw config settings without expansion

From: Alice Mitchell <[email protected]>

Config entries sometimes contain variable expansions, this adds options
to retrieve the config entry rather than its current expanded value.

Signed-off-by: Alice Mitchell <[email protected]>
Signed-off-by: Steve Dickson <[email protected]>
---
support/include/conffile.h | 1 +
support/nfs/conffile.c | 23 +++++++++++++++++++++++
tools/nfsconf/nfsconf.man | 10 +++++++++-
tools/nfsconf/nfsconfcli.c | 22 ++++++++++++++++------
4 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/support/include/conffile.h b/support/include/conffile.h
index 7d974fe9..c4a3ca62 100644
--- a/support/include/conffile.h
+++ b/support/include/conffile.h
@@ -61,6 +61,7 @@ extern _Bool conf_get_bool(const char *, const char *, _Bool);
extern char *conf_get_str(const char *, const char *);
extern char *conf_get_str_with_def(const char *, const char *, char *);
extern char *conf_get_section(const char *, const char *, const char *);
+extern char *conf_get_entry(const char *, const char *, const char *);
extern int conf_init_file(const char *);
extern void conf_cleanup(void);
extern int conf_match_num(const char *, const char *, int);
diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index 1e15e7d5..fd4a17ad 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -891,6 +891,29 @@ conf_get_str_with_def(const char *section, const char *tag, char *def)
return result;
}

+/*
+ * Retrieve an entry without interpreting its contents
+ */
+char *
+conf_get_entry(const char *section, const char *arg, const char *tag)
+{
+ struct conf_binding *cb;
+
+ cb = LIST_FIRST (&conf_bindings[conf_hash (section)]);
+ for (; cb; cb = LIST_NEXT (cb, link)) {
+ if (strcasecmp(section, cb->section) != 0)
+ continue;
+ if (arg && (cb->arg == NULL || strcasecmp(arg, cb->arg) != 0))
+ continue;
+ if (!arg && cb->arg)
+ continue;
+ if (strcasecmp(tag, cb->tag) != 0)
+ continue;
+ return cb->value;
+ }
+ return 0;
+}
+
/*
* Find a section that may or may not have an argument
*/
diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man
index 30791988..d44e86fb 100644
--- a/tools/nfsconf/nfsconf.man
+++ b/tools/nfsconf/nfsconf.man
@@ -11,6 +11,12 @@ nfsconf \- Query various NFS configuration settings
.IR infile.conf ]
.RI [ outfile ]
.P
+.B nfsconf \-\-entry
+.RB [ \-\-arg
+.IR subsection]
+.IR section
+.IR tag
+.P
.B nfsconf \-\-get
.RB [ \-v | \-\-verbose ]
.RB [ \-f | \-\-file
@@ -58,6 +64,8 @@ from a range of nfs-utils configuration files.
The following modes are available:
.IP "\fB\-d, \-\-dump\fP"
Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output.
+.IP "\fB\-e, \-\-entry\fP"
+retrieve the config entry rather than its current expanded value
.IP "\fB\-i, \-\-isset\fP"
Test if a specific tag has a value set.
.IP "\fB\-g, \-\-get\fP"
@@ -75,7 +83,7 @@ Increase verbosity and print debugging information.
.B \-f, \-\-file \fIinfile\fR
Select a different config file to operate upon, default is
.I /etc/nfs.conf
-.SS Options only valid in \fB\-\-get\fR and \fB\-\-isset\fR modes.
+.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes.
.TP
.B \-a, \-\-arg \fIsubsection\fR
Select a specific sub-section
diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c
index 361d386e..b2ef96d1 100644
--- a/tools/nfsconf/nfsconfcli.c
+++ b/tools/nfsconf/nfsconfcli.c
@@ -11,6 +11,7 @@
typedef enum {
MODE_NONE,
MODE_GET,
+ MODE_ENTRY,
MODE_ISSET,
MODE_DUMP,
MODE_SET,
@@ -30,6 +31,8 @@ static void usage(const char *name)
fprintf(stderr, " Outputs the configuration to the named file\n");
fprintf(stderr, " --get [--arg subsection] {section} {tag}\n");
fprintf(stderr, " Output one specific config value\n");
+ fprintf(stderr, " --entry [--arg subsection] {section} {tag}\n");
+ fprintf(stderr, " Output the uninterpreted config entry\n");
fprintf(stderr, " --isset [--arg subsection] {section} {tag}\n");
fprintf(stderr, " Return code indicates if config value is present\n");
fprintf(stderr, " --set [--arg subsection] {section} {tag} {value}\n");
@@ -55,6 +58,7 @@ int main(int argc, char **argv)
int index = 0;
struct option long_options[] = {
{"get", no_argument, 0, 'g' },
+ {"entry", no_argument, 0, 'e' },
{"set", no_argument, 0, 's' },
{"unset", no_argument, 0, 'u' },
{"arg", required_argument, 0, 'a' },
@@ -66,7 +70,7 @@ int main(int argc, char **argv)
{NULL, 0, 0, 0 }
};

- c = getopt_long(argc, argv, "gsua:id::f:vm:", long_options, &index);
+ c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index);
if (c == -1) break;

switch (c) {
@@ -86,6 +90,9 @@ int main(int argc, char **argv)
case 'g':
mode = MODE_GET;
break;
+ case 'e':
+ mode = MODE_ENTRY;
+ break;
case 's':
mode = MODE_SET;
break;
@@ -167,8 +174,8 @@ int main(int argc, char **argv)
if (dumpfile)
fclose(out);
} else
- /* --iset and --get share a lot of code */
- if (mode == MODE_GET || mode == MODE_ISSET) {
+ /* --isset and --get share a lot of code */
+ if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) {
char * section = NULL;
char * tag = NULL;
const char * val;
@@ -186,14 +193,17 @@ int main(int argc, char **argv)
tag = argv[optind++];

/* retrieve the specified tags value */
- val = conf_get_section(section, arg, tag);
+ if (mode == MODE_ENTRY)
+ val = conf_get_entry(section, arg, tag);
+ else
+ val = conf_get_section(section, arg, tag);
if (val != NULL) {
/* ret=0, success, mode --get wants to output the value as well */
- if (mode == MODE_GET)
+ if (mode != MODE_ISSET)
printf("%s\n", val);
} else {
/* ret=1, no value found, tell the user if they asked */
- if (mode == MODE_GET && verbose)
+ if (mode != MODE_ISSET && verbose)
fprintf(stderr, "Tag '%s' not found\n", tag);
ret = 1;
}
--
2.30.2


2021-05-06 17:29:41

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH 1/3] nfs-utils: Enable the retrieval of raw config settings without expansion



On 4/14/21 2:10 PM, Steve Dickson wrote:
> From: Alice Mitchell <[email protected]>
>
> Config entries sometimes contain variable expansions, this adds options
> to retrieve the config entry rather than its current expanded value.
>
> Signed-off-by: Alice Mitchell <[email protected]>
> Signed-off-by: Steve Dickson <[email protected]>
> ---
> support/include/conffile.h | 1 +
> support/nfs/conffile.c | 23 +++++++++++++++++++++++
> tools/nfsconf/nfsconf.man | 10 +++++++++-
> tools/nfsconf/nfsconfcli.c | 22 ++++++++++++++++------
> 4 files changed, 49 insertions(+), 7 deletions(-)
Committed (tag: nfs-utils-2-5-4-rc3)

steved.
>
> diff --git a/support/include/conffile.h b/support/include/conffile.h
> index 7d974fe9..c4a3ca62 100644
> --- a/support/include/conffile.h
> +++ b/support/include/conffile.h
> @@ -61,6 +61,7 @@ extern _Bool conf_get_bool(const char *, const char *, _Bool);
> extern char *conf_get_str(const char *, const char *);
> extern char *conf_get_str_with_def(const char *, const char *, char *);
> extern char *conf_get_section(const char *, const char *, const char *);
> +extern char *conf_get_entry(const char *, const char *, const char *);
> extern int conf_init_file(const char *);
> extern void conf_cleanup(void);
> extern int conf_match_num(const char *, const char *, int);
> diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
> index 1e15e7d5..fd4a17ad 100644
> --- a/support/nfs/conffile.c
> +++ b/support/nfs/conffile.c
> @@ -891,6 +891,29 @@ conf_get_str_with_def(const char *section, const char *tag, char *def)
> return result;
> }
>
> +/*
> + * Retrieve an entry without interpreting its contents
> + */
> +char *
> +conf_get_entry(const char *section, const char *arg, const char *tag)
> +{
> + struct conf_binding *cb;
> +
> + cb = LIST_FIRST (&conf_bindings[conf_hash (section)]);
> + for (; cb; cb = LIST_NEXT (cb, link)) {
> + if (strcasecmp(section, cb->section) != 0)
> + continue;
> + if (arg && (cb->arg == NULL || strcasecmp(arg, cb->arg) != 0))
> + continue;
> + if (!arg && cb->arg)
> + continue;
> + if (strcasecmp(tag, cb->tag) != 0)
> + continue;
> + return cb->value;
> + }
> + return 0;
> +}
> +
> /*
> * Find a section that may or may not have an argument
> */
> diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man
> index 30791988..d44e86fb 100644
> --- a/tools/nfsconf/nfsconf.man
> +++ b/tools/nfsconf/nfsconf.man
> @@ -11,6 +11,12 @@ nfsconf \- Query various NFS configuration settings
> .IR infile.conf ]
> .RI [ outfile ]
> .P
> +.B nfsconf \-\-entry
> +.RB [ \-\-arg
> +.IR subsection]
> +.IR section
> +.IR tag
> +.P
> .B nfsconf \-\-get
> .RB [ \-v | \-\-verbose ]
> .RB [ \-f | \-\-file
> @@ -58,6 +64,8 @@ from a range of nfs-utils configuration files.
> The following modes are available:
> .IP "\fB\-d, \-\-dump\fP"
> Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output.
> +.IP "\fB\-e, \-\-entry\fP"
> +retrieve the config entry rather than its current expanded value
> .IP "\fB\-i, \-\-isset\fP"
> Test if a specific tag has a value set.
> .IP "\fB\-g, \-\-get\fP"
> @@ -75,7 +83,7 @@ Increase verbosity and print debugging information.
> .B \-f, \-\-file \fIinfile\fR
> Select a different config file to operate upon, default is
> .I /etc/nfs.conf
> -.SS Options only valid in \fB\-\-get\fR and \fB\-\-isset\fR modes.
> +.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes.
> .TP
> .B \-a, \-\-arg \fIsubsection\fR
> Select a specific sub-section
> diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c
> index 361d386e..b2ef96d1 100644
> --- a/tools/nfsconf/nfsconfcli.c
> +++ b/tools/nfsconf/nfsconfcli.c
> @@ -11,6 +11,7 @@
> typedef enum {
> MODE_NONE,
> MODE_GET,
> + MODE_ENTRY,
> MODE_ISSET,
> MODE_DUMP,
> MODE_SET,
> @@ -30,6 +31,8 @@ static void usage(const char *name)
> fprintf(stderr, " Outputs the configuration to the named file\n");
> fprintf(stderr, " --get [--arg subsection] {section} {tag}\n");
> fprintf(stderr, " Output one specific config value\n");
> + fprintf(stderr, " --entry [--arg subsection] {section} {tag}\n");
> + fprintf(stderr, " Output the uninterpreted config entry\n");
> fprintf(stderr, " --isset [--arg subsection] {section} {tag}\n");
> fprintf(stderr, " Return code indicates if config value is present\n");
> fprintf(stderr, " --set [--arg subsection] {section} {tag} {value}\n");
> @@ -55,6 +58,7 @@ int main(int argc, char **argv)
> int index = 0;
> struct option long_options[] = {
> {"get", no_argument, 0, 'g' },
> + {"entry", no_argument, 0, 'e' },
> {"set", no_argument, 0, 's' },
> {"unset", no_argument, 0, 'u' },
> {"arg", required_argument, 0, 'a' },
> @@ -66,7 +70,7 @@ int main(int argc, char **argv)
> {NULL, 0, 0, 0 }
> };
>
> - c = getopt_long(argc, argv, "gsua:id::f:vm:", long_options, &index);
> + c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index);
> if (c == -1) break;
>
> switch (c) {
> @@ -86,6 +90,9 @@ int main(int argc, char **argv)
> case 'g':
> mode = MODE_GET;
> break;
> + case 'e':
> + mode = MODE_ENTRY;
> + break;
> case 's':
> mode = MODE_SET;
> break;
> @@ -167,8 +174,8 @@ int main(int argc, char **argv)
> if (dumpfile)
> fclose(out);
> } else
> - /* --iset and --get share a lot of code */
> - if (mode == MODE_GET || mode == MODE_ISSET) {
> + /* --isset and --get share a lot of code */
> + if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) {
> char * section = NULL;
> char * tag = NULL;
> const char * val;
> @@ -186,14 +193,17 @@ int main(int argc, char **argv)
> tag = argv[optind++];
>
> /* retrieve the specified tags value */
> - val = conf_get_section(section, arg, tag);
> + if (mode == MODE_ENTRY)
> + val = conf_get_entry(section, arg, tag);
> + else
> + val = conf_get_section(section, arg, tag);
> if (val != NULL) {
> /* ret=0, success, mode --get wants to output the value as well */
> - if (mode == MODE_GET)
> + if (mode != MODE_ISSET)
> printf("%s\n", val);
> } else {
> /* ret=1, no value found, tell the user if they asked */
> - if (mode == MODE_GET && verbose)
> + if (mode != MODE_ISSET && verbose)
> fprintf(stderr, "Tag '%s' not found\n", tag);
> ret = 1;
> }
>