diff options
Diffstat (limited to '')
-rw-r--r-- | tools/nfsconf/nfsconfcli.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c new file mode 100644 index 0000000..b2ef96d --- /dev/null +++ b/tools/nfsconf/nfsconfcli.c @@ -0,0 +1,253 @@ +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <getopt.h> +#include <string.h> +#include <errno.h> +#include "config.h" +#include "conffile.h" +#include "xlog.h" + +typedef enum { + MODE_NONE, + MODE_GET, + MODE_ENTRY, + MODE_ISSET, + MODE_DUMP, + MODE_SET, + MODE_UNSET +} confmode_t; + +static void usage(const char *name) +{ + fprintf(stderr, "Usage: %s [-v] [--file filename.conf] ...\n", name); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -v Increase Verbosity\n"); + fprintf(stderr, " --file filename.conf Load this config file\n"); + fprintf(stderr, " (Default config file: " NFS_CONFFILE "\n"); + fprintf(stderr, " --modified \"info\" Use \"info\" in file modified header\n"); + fprintf(stderr, "Modes:\n"); + fprintf(stderr, " --dump [outputfile]\n"); + 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"); + fprintf(stderr, " Set and Write a config value\n"); + fprintf(stderr, " --unset [--arg subsection] {section} {tag}\n"); + fprintf(stderr, " Remove an existing config value\n"); +} + +int main(int argc, char **argv) +{ + char * confpath = NFS_CONFFILE; + char * arg = NULL; + int verbose=0; + int ret = 0; + char * dumpfile = NULL; + + confmode_t mode = MODE_NONE; + + modified_by = "Modified by nfsconf"; + + while (1) { + int c; + 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' }, + {"isset", no_argument, 0, 'i' }, + {"dump", optional_argument, 0, 'd' }, + {"file", required_argument, 0, 'f' }, + {"verbose", no_argument, 0, 'v' }, + {"modified", required_argument, 0, 'm' }, + {NULL, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index); + if (c == -1) break; + + switch (c) { + case 0: + break; + case 'f': + /* user specified source path for config */ + confpath = optarg; + break; + case 'a': + /* user supplied a sub-section name */ + arg = optarg; + break; + case 'v': + verbose++; + break; + case 'g': + mode = MODE_GET; + break; + case 'e': + mode = MODE_ENTRY; + break; + case 's': + mode = MODE_SET; + break; + case 'u': + mode = MODE_UNSET; + break; + case 'i': + mode = MODE_ISSET; + break; + case 'd': + /* check if user supplied a filename for dump */ + if (optarg == NULL && argv[optind] != NULL + && argv[optind][0] != '-') + optarg = argv[optind++]; + mode = MODE_DUMP; + dumpfile = optarg; + break; + case 'm': + if (optarg == NULL || *optarg == 0) + modified_by = NULL; + else + modified_by = optarg; + break; + default: + usage(argv[0]); + return 1; + } + } + + /* configure the logging that conffile.c uses */ + if (verbose) + xlog_config(D_ALL, 1); + xlog_stderr(1); + xlog_syslog(0); + xlog_open("nfsconf"); + + if (mode == MODE_NONE) { + fprintf(stderr, "Error: No MODE selected.\n"); + usage(argv[0]); + return 1; + } + + if (mode != MODE_SET && mode != MODE_UNSET) { + if (conf_init_file(confpath)) { + /* config file was missing or had an error, warn about it */ + if (verbose || mode != MODE_ISSET) { + fprintf(stderr, "Error loading config file %s\n", + confpath); + } + + /* this isnt fatal for --isset */ + if (mode != MODE_ISSET) + return 1; + } + } + + /* --dump mode, output the current configuration */ + if (mode == MODE_DUMP) { + /* default to writing it to stdout */ + FILE *out = stdout; + + /* user specified a file to write to instead */ + if (dumpfile) { + out = fopen(dumpfile, "w"); + if (out == NULL) { + fprintf(stderr, "Error opening dumpfile %s: %s\n", + dumpfile, strerror(errno)); + ret = 2; + goto cleanup; + } + if (verbose) + printf("Dumping config to %s\n", dumpfile); + } + + /* output the configuration */ + conf_report(out); + + /* close that user specified file */ + if (dumpfile) + fclose(out); + } else + /* --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; + + /* test they supplied section and tag names */ + if (optind+1 >= argc) { + fprintf(stderr, "Error: insufficient arguments for mode\n"); + usage(argv[0]); + ret = 2; + goto cleanup; + } + + /* now we have a section and tag name */ + section = argv[optind++]; + tag = argv[optind++]; + + /* retrieve the specified tags value */ + 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_ISSET) + printf("%s\n", val); + } else { + /* ret=1, no value found, tell the user if they asked */ + if (mode != MODE_ISSET && verbose) + fprintf(stderr, "Tag '%s' not found\n", tag); + ret = 1; + } + } else + if (mode == MODE_SET || mode == MODE_UNSET) { + char * section = NULL; + char * tag = NULL; + char * val = NULL; + int need = 2; + + if (mode == MODE_UNSET) + need = 1; + + /* test they supplied section and tag names */ + if (optind+need >= argc) { + fprintf(stderr, "Error: insufficient arguments for mode\n"); + usage(argv[0]); + ret = 2; + goto cleanup; + } + + /* now we have a section and tag name */ + section = argv[optind++]; + tag = argv[optind++]; + if (mode == MODE_SET) + val = argv[optind++]; + + /* setting an empty string is same as unsetting */ + if (val!=NULL && *val == '\0') { + mode = MODE_UNSET; + val = NULL; + } + + if (conf_write(confpath, section, arg, tag, val)) { + if (verbose) + fprintf(stderr, "Error writing config\n"); + ret = 1; + } + } else { + fprintf(stderr, "Mode not yet implemented.\n"); + ret = 2; + } + +cleanup: + conf_cleanup(); + return ret; +} |