top: Do not default to the cwd in configs_read().
If the HOME environment variable is not set, or not absolute, use the home directory returned by getpwuid(getuid()), if set and absolute (instead of the cwd "."); otherwise, set p_home to NULL. To keep the changes to a minimum, we rely on POSIX, which requires that fopen() fails with ENOENT if the pathname (Rc_name) is an empty string. This integrates well into the existing code, and makes write_rcfile() work without a change. Also, it makes the code in configs_read() easier to follow: only set and use p_home if safe, and only set Rc_name if safe (in all the other cases it is the empty string, and the fopen() calls fail). Plus, check for snprintf() truncation (and if it happens, reset Rc_name to the empty string). Important note: top.1 should probably be updated, since it mentions the fallback to the current working directory.
This commit is contained in:
parent
e877d4f4c4
commit
b45c4803dd
33
top/top.c
33
top/top.c
@ -3810,6 +3810,20 @@ error Hey, fix the above fscanf 'PFLAGSSIZ' dependency !
|
|||||||
} // end: config_file
|
} // end: config_file
|
||||||
|
|
||||||
|
|
||||||
|
static int snprintf_Rc_name (const char *const format, ...) __attribute__((format(printf,1,2)));
|
||||||
|
static int snprintf_Rc_name (const char *const format, ...) {
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
len = vsnprintf(Rc_name, sizeof(Rc_name), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (len <= 0 || (size_t)len >= sizeof(Rc_name)) {
|
||||||
|
Rc_name[0] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try reading up to 3 rcfiles
|
* Try reading up to 3 rcfiles
|
||||||
* 1. 'SYS_RCRESTRICT' contains two lines consisting of the secure
|
* 1. 'SYS_RCRESTRICT' contains two lines consisting of the secure
|
||||||
@ -3842,23 +3856,31 @@ static void configs_read (void) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rc_name[0] = '\0'; // "fopen() shall fail if pathname is an empty string."
|
||||||
// attempt to use the legacy file first, if we cannot access that file, use
|
// attempt to use the legacy file first, if we cannot access that file, use
|
||||||
// the new XDG basedir locations (XDG_CONFIG_HOME or HOME/.config) instead.
|
// the new XDG basedir locations (XDG_CONFIG_HOME or HOME/.config) instead.
|
||||||
p_home = getenv("HOME");
|
p_home = getenv("HOME");
|
||||||
if (!p_home || p_home[0] == '\0')
|
if (!p_home || p_home[0] != '/') {
|
||||||
p_home = ".";
|
const struct passwd *const pwd = getpwuid(getuid());
|
||||||
snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", p_home, Myname);
|
if (!pwd || !(p_home = pwd->pw_dir) || p_home[0] != '/') {
|
||||||
|
p_home = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p_home) {
|
||||||
|
snprintf_Rc_name("%s/.%src", p_home, Myname);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(fp = fopen(Rc_name, "r"))) {
|
if (!(fp = fopen(Rc_name, "r"))) {
|
||||||
p = getenv("XDG_CONFIG_HOME");
|
p = getenv("XDG_CONFIG_HOME");
|
||||||
// ensure the path we get is absolute, fallback otherwise.
|
// ensure the path we get is absolute, fallback otherwise.
|
||||||
if (!p || p[0] != '/') {
|
if (!p || p[0] != '/') {
|
||||||
|
if (!p_home) goto system_default;
|
||||||
p = fmtmk("%s/.config", p_home);
|
p = fmtmk("%s/.config", p_home);
|
||||||
(void)mkdir(p, 0700);
|
(void)mkdir(p, 0700);
|
||||||
}
|
}
|
||||||
snprintf(Rc_name, sizeof(Rc_name), "%s/procps", p);
|
if (!snprintf_Rc_name("%s/procps", p)) goto system_default;
|
||||||
(void)mkdir(Rc_name, 0700);
|
(void)mkdir(Rc_name, 0700);
|
||||||
snprintf(Rc_name, sizeof(Rc_name), "%s/procps/%src", p, Myname);
|
if (!snprintf_Rc_name("%s/procps/%src", p, Myname)) goto system_default;
|
||||||
fp = fopen(Rc_name, "r");
|
fp = fopen(Rc_name, "r");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3867,6 +3889,7 @@ static void configs_read (void) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (p) goto default_or_error;
|
if (p) goto default_or_error;
|
||||||
} else {
|
} else {
|
||||||
|
system_default:
|
||||||
fp = fopen(SYS_RCDEFAULTS, "r");
|
fp = fopen(SYS_RCDEFAULTS, "r");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
p = config_file(fp, SYS_RCDEFAULTS, &tmp_delay);
|
p = config_file(fp, SYS_RCDEFAULTS, &tmp_delay);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user