summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2022-11-06 13:37:33 +0100
committerYorhel <git@yorhel.nl>2022-11-06 13:37:33 +0100
commit49e4b061a56eeb319e3037f89252678c779156d0 (patch)
tree4031658b6802d60ed94ebe15368d37240481b748
parentb45f8e4c0634ef04b075b559f0025a21bfc8545f (diff)
Backport configuration file support from 2.x
-rw-r--r--doc/ncdu.pod23
-rw-r--r--src/dir_common.c2
-rw-r--r--src/exclude.c3
-rw-r--r--src/main.c76
-rw-r--r--src/util.c6
-rw-r--r--src/util.h2
6 files changed, 105 insertions, 7 deletions
diff --git a/doc/ncdu.pod b/doc/ncdu.pod
index f0c28bd..5d18805 100644
--- a/doc/ncdu.pod
+++ b/doc/ncdu.pod
@@ -70,6 +70,10 @@ information.
This enables viewing and sorting by the latest child mtime, or modified time,
using 'm' and 'M', respectively.
+=item B<--ignore-config>
+
+Do not attempt to load any configuration files.
+
=back
=head2 Scan Options
@@ -253,6 +257,25 @@ The default is I<dark-bg> unless the C<NO_COLOR> environment variable is set.
=back
+=head1 CONFIGURATION
+
+Ncdu can be configured by placing command-line options in C</etc/ncdu.conf> or
+C<$HOME/.config/ncdu/config>. If both files exist, the system configuration
+will be loaded before the user configuration, allowing users to override
+options set in the system configuration. Options given on the command line will
+override options set in the configuration files. The files will not be read at
+all when C<--ignore-config> is given on the command line.
+
+The configuration file format is simply one command line option per line. Lines
+starting with C<#> are ignored. Example configuration file:
+
+ # Always enable extended mode
+ -e
+
+ # Exclude .git directories
+ --exclude .git
+
+
=head1 KEYS
=over
diff --git a/src/dir_common.c b/src/dir_common.c
index 0a77260..2acc7ea 100644
--- a/src/dir_common.c
+++ b/src/dir_common.c
@@ -35,7 +35,7 @@ int (*dir_process)(void);
char *dir_curpath; /* Full path of the last seen item. */
struct dir_output dir_output;
char *dir_fatalerr; /* Error message on a fatal error. (NULL if there was no fatal error) */
-int dir_ui; /* User interface to use */
+int dir_ui = -1; /* User interface to use */
static int confirm_quit_while_scanning_stage_1_passed; /* Additional check before quitting */
static char *lasterr; /* Path where the last error occurred. */
static int curpathl; /* Allocated length of dir_curpath */
diff --git a/src/exclude.c b/src/exclude.c
index c1c018d..b6eb437 100644
--- a/src/exclude.c
+++ b/src/exclude.c
@@ -46,8 +46,7 @@ void exclude_add(char *pat) {
n = &((*n)->next);
*n = (struct exclude *) xcalloc(1, sizeof(struct exclude));
- (*n)->pattern = (char *) xmalloc(strlen(pat)+1);
- strcpy((*n)->pattern, pat);
+ (*n)->pattern = xstrdup(pat);
}
diff --git a/src/main.c b/src/main.c
index 30619ec..222514d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -294,16 +294,81 @@ static void arg_help(void) {
}
+static void config_read(const char *fn) {
+ FILE *f;
+ char buf[1024], *line, *tmp, **args = NULL, **argsi;
+ int r, len, argslen = 0, argssize = 0;
+
+ if((f = fopen(fn, "r")) == NULL) {
+ if(errno == ENOENT || errno == ENOTDIR) return;
+ die("Error opening %s: %s.\nRun with --ignore-config to skip reading config files.\n", fn, strerror(errno));
+ }
+
+ while(fgets(buf, 1024, f) != NULL) {
+ line = buf;
+ while(*line == ' ' || *line == '\t') line++;
+ len = strlen(line);
+ while(len > 0 && (line[len-1] == ' ' || line[len-1] == '\t' || line[len-1] == '\r' || line[len-1] == '\n')) len -= 1;
+ line[len] = 0;
+ if(len == 0 || *line == '#') continue;
+
+ /* Reserve at least 3 spots, one for the option, one for a possible argument and one for the final NULL. */
+ if(argslen+3 >= argssize) {
+ argssize = argssize ? argssize*2 : 32;
+ args = xrealloc(args, sizeof(char *)*argssize);
+ }
+ for(tmp=line; *tmp && *tmp != ' ' && *tmp != '\t' && *tmp != '='; tmp++);
+ while(*tmp && (*tmp == ' ' || *tmp == '\t')) {
+ *tmp = 0;
+ tmp++;
+ }
+ args[argslen++] = xstrdup(line);
+ if(*tmp) args[argslen++] = xstrdup(tmp);
+ }
+ if(ferror(f))
+ die("Error reading from %s: %s\nRun with --ignore-config to skip reading config files.\n", fn, strerror(errno));
+ fclose(f);
+ if(!argslen) return;
+
+ args[argslen] = NULL;
+ memset(&argparser_state, 0, sizeof(struct argparser));
+ argparser_state.argv = args;
+ argparser_state.argc = argslen;
+
+ while((r = argparser_next(&argparser_state)) > 0)
+ if(r == 2 || !arg_option())
+ die("Unknown option in config file '%s': %s.\nRun with --ignore-config to skip reading config files.\n", fn, argparser_state.last);
+
+ for(argsi=args; argsi && *argsi; argsi++) free(*argsi);
+ free(args);
+}
+
+
+static void config_load(int argc, char **argv) {
+ char *env, buf[1024];
+ int r;
+
+ for(r=0; r<argc; r++)
+ if(strcmp(argv[r], "--ignore-config") == 0) return;
+
+ config_read("/etc/ncdu.conf");
+
+ if((env = getenv("XDG_CONFIG_HOME")) != NULL) {
+ r = snprintf(buf, 1024, "%s/ncdu/config", env);
+ if(r > 0 && r < 1024) config_read(buf);
+ } else if((env = getenv("HOME")) != NULL) {
+ r = snprintf(buf, 1024, "%s/.config/ncdu/config", env);
+ if(r > 0 && r < 1024) config_read(buf);
+ }
+}
+
+
static void argv_parse(int argc, char **argv) {
int r;
char *export = NULL;
char *import = NULL;
char *dir = NULL;
- uic_theme = getenv("NO_COLOR") ? 0 : 2;
- dir_ui = -1;
- si = 0;
-
memset(&argparser_state, 0, sizeof(struct argparser));
argparser_state.argv = argv;
argparser_state.argc = argc;
@@ -317,6 +382,7 @@ static void argv_parse(int argc, char **argv) {
} else if(OPT("-h") || OPT("-?") || OPT("--help")) arg_help();
else if(OPT("-o")) export = ARG;
else if(OPT("-f")) import = ARG;
+ else if(OPT("--ignore-config")) {}
else if(!arg_option()) die("Unknown option '%s'.\n", argparser_state.last);
}
@@ -392,6 +458,8 @@ void close_nc(void) {
int main(int argc, char **argv) {
read_locale();
+ uic_theme = getenv("NO_COLOR") ? 0 : 2;
+ config_load(argc, argv);
argv_parse(argc, argv);
if(dir_ui == 2)
diff --git a/src/util.c b/src/util.c
index ed20b69..16f7a39 100644
--- a/src/util.c
+++ b/src/util.c
@@ -449,3 +449,9 @@ void addparentstats(struct dir *d, int64_t size, int64_t asize, uint64_t mtime,
void *xmalloc(size_t size) { wrap_oom(malloc(size)) }
void *xcalloc(size_t n, size_t size) { wrap_oom(calloc(n, size)) }
void *xrealloc(void *mem, size_t size) { wrap_oom(realloc(mem, size)) }
+
+char *xstrdup(const char *str) {
+ char *r = xmalloc(strlen(str)+1);
+ strcpy(r, str);
+ return r;
+}
diff --git a/src/util.h b/src/util.h
index 516c5e7..4d69951 100644
--- a/src/util.h
+++ b/src/util.h
@@ -188,5 +188,7 @@ void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
void *xrealloc(void *, size_t);
+char *xstrdup(const char *);
+
#endif