config(8): De-dupe hint/env vars within a single file
r335653 flipped the order in which hints/env files are concatenated to match the order in which vars are processed by the kernel. This is the other hammer to drop. Use nv(9) to de-dupe entries within a single `hint` or `env` file, using the latest value specified for a key. This leaves some duplicates if a variable is specified in multiple hint/env files or via `envvar` in a kernel config, but the reversed order of concatenation (from r335653) makes this a non-issue as the latest-specified version will be seen first. This change also silently rewrote hint bits to use the same sanitization process that ian@ wrote for r335642. To the kernel, hints and env vars are basically the same thing through early boot, then get merged into the dynamic environment once kmem becomes available and the dynamic environment is created. They should be subjected to the same restrictions. MFC after: 1 month
This commit is contained in:
parent
945a6b310b
commit
51c854f028
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336011
@ -18,7 +18,7 @@ CFLAGS+= -I. -I${SRCDIR}
|
|||||||
|
|
||||||
NO_WMISSING_VARIABLE_DECLARATIONS=
|
NO_WMISSING_VARIABLE_DECLARATIONS=
|
||||||
|
|
||||||
LIBADD= l sbuf
|
LIBADD= l nv sbuf
|
||||||
|
|
||||||
CLEANFILES+= kernconf.c
|
CLEANFILES+= kernconf.c
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ static const char rcsid[] =
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/cnv.h>
|
||||||
|
#include <sys/nv.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include "y.tab.h"
|
#include "y.tab.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -62,6 +64,10 @@ static void do_objs(FILE *);
|
|||||||
static void do_before_depend(FILE *);
|
static void do_before_depend(FILE *);
|
||||||
static int opteq(const char *, const char *);
|
static int opteq(const char *, const char *);
|
||||||
static void read_files(void);
|
static void read_files(void);
|
||||||
|
static void sanitize_envline(char *result, const char *src);
|
||||||
|
static void process_into_file(char *line, FILE *ofp);
|
||||||
|
static void process_into_nvlist(char *line, nvlist_t *nvl);
|
||||||
|
static void dump_nvlist(nvlist_t *nvl, FILE *ofp);
|
||||||
|
|
||||||
static void errout(const char *fmt, ...)
|
static void errout(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -180,64 +186,6 @@ makefile(void)
|
|||||||
moveifchanged(path("Makefile.new"), path("Makefile"));
|
moveifchanged(path("Makefile.new"), path("Makefile"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Build hints.c from the skeleton
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
makehints(void)
|
|
||||||
{
|
|
||||||
FILE *ifp, *ofp;
|
|
||||||
char line[BUFSIZ];
|
|
||||||
char *s;
|
|
||||||
struct hint *hint;
|
|
||||||
|
|
||||||
ofp = fopen(path("hints.c.new"), "w");
|
|
||||||
if (ofp == NULL)
|
|
||||||
err(1, "%s", path("hints.c.new"));
|
|
||||||
fprintf(ofp, "#include <sys/types.h>\n");
|
|
||||||
fprintf(ofp, "#include <sys/systm.h>\n");
|
|
||||||
fprintf(ofp, "\n");
|
|
||||||
fprintf(ofp, "char static_hints[] = {\n");
|
|
||||||
STAILQ_FOREACH(hint, &hints, hint_next) {
|
|
||||||
ifp = fopen(hint->hint_name, "r");
|
|
||||||
if (ifp == NULL)
|
|
||||||
err(1, "%s", hint->hint_name);
|
|
||||||
while (fgets(line, BUFSIZ, ifp) != NULL) {
|
|
||||||
/* zap trailing CR and/or LF */
|
|
||||||
while ((s = strrchr(line, '\n')) != NULL)
|
|
||||||
*s = '\0';
|
|
||||||
while ((s = strrchr(line, '\r')) != NULL)
|
|
||||||
*s = '\0';
|
|
||||||
/* remove # comments */
|
|
||||||
s = strchr(line, '#');
|
|
||||||
if (s)
|
|
||||||
*s = '\0';
|
|
||||||
/* remove any whitespace and " characters */
|
|
||||||
s = line;
|
|
||||||
while (*s) {
|
|
||||||
if (*s == ' ' || *s == '\t' || *s == '"') {
|
|
||||||
while (*s) {
|
|
||||||
s[0] = s[1];
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
/* start over */
|
|
||||||
s = line;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
/* anything left? */
|
|
||||||
if (*line == '\0')
|
|
||||||
continue;
|
|
||||||
fprintf(ofp, "\"%s\\0\"\n", line);
|
|
||||||
}
|
|
||||||
fclose(ifp);
|
|
||||||
}
|
|
||||||
fprintf(ofp, "\"\\0\"\n};\n");
|
|
||||||
fclose(ofp);
|
|
||||||
moveifchanged(path("hints.c.new"), path("hints.c"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sanitize_envline(char *result, const char *src)
|
sanitize_envline(char *result, const char *src)
|
||||||
{
|
{
|
||||||
@ -295,6 +243,87 @@ sanitize_envline(char *result, const char *src)
|
|||||||
*dst = 0;
|
*dst = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_into_file(char *line, FILE *ofp)
|
||||||
|
{
|
||||||
|
char result[BUFSIZ];
|
||||||
|
|
||||||
|
sanitize_envline(result, line);
|
||||||
|
/* anything left? */
|
||||||
|
if (*result == '\0')
|
||||||
|
return;
|
||||||
|
fprintf(ofp, "\"%s\\0\"\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_into_nvlist(char *line, nvlist_t *nvl)
|
||||||
|
{
|
||||||
|
char result[BUFSIZ], *s;
|
||||||
|
|
||||||
|
sanitize_envline(result, line);
|
||||||
|
/* anything left? */
|
||||||
|
if (*result == '\0')
|
||||||
|
return;
|
||||||
|
s = strchr(result, '=');
|
||||||
|
*s = 0;
|
||||||
|
if (nvlist_exists(nvl, result))
|
||||||
|
nvlist_free(nvl, result);
|
||||||
|
nvlist_add_string(nvl, result, s + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_nvlist(nvlist_t *nvl, FILE *ofp)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
void *cookie;
|
||||||
|
|
||||||
|
if (nvl == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (!nvlist_empty(nvl)) {
|
||||||
|
cookie = NULL;
|
||||||
|
name = nvlist_next(nvl, NULL, &cookie);
|
||||||
|
fprintf(ofp, "\"%s=%s\\0\"\n", name,
|
||||||
|
cnvlist_get_string(cookie));
|
||||||
|
|
||||||
|
cnvlist_free_string(nvl, cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build hints.c from the skeleton
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
makehints(void)
|
||||||
|
{
|
||||||
|
FILE *ifp, *ofp;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
char line[BUFSIZ];
|
||||||
|
struct hint *hint;
|
||||||
|
|
||||||
|
ofp = fopen(path("hints.c.new"), "w");
|
||||||
|
if (ofp == NULL)
|
||||||
|
err(1, "%s", path("hints.c.new"));
|
||||||
|
fprintf(ofp, "#include <sys/types.h>\n");
|
||||||
|
fprintf(ofp, "#include <sys/systm.h>\n");
|
||||||
|
fprintf(ofp, "\n");
|
||||||
|
fprintf(ofp, "char static_hints[] = {\n");
|
||||||
|
nvl = nvlist_create(0);
|
||||||
|
STAILQ_FOREACH(hint, &hints, hint_next) {
|
||||||
|
ifp = fopen(hint->hint_name, "r");
|
||||||
|
if (ifp == NULL)
|
||||||
|
err(1, "%s", hint->hint_name);
|
||||||
|
while (fgets(line, BUFSIZ, ifp) != NULL)
|
||||||
|
process_into_nvlist(line, nvl);
|
||||||
|
dump_nvlist(nvl, ofp);
|
||||||
|
fclose(ifp);
|
||||||
|
}
|
||||||
|
nvlist_destroy(nvl);
|
||||||
|
fprintf(ofp, "\"\\0\"\n};\n");
|
||||||
|
fclose(ofp);
|
||||||
|
moveifchanged(path("hints.c.new"), path("hints.c"));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build env.c from the skeleton
|
* Build env.c from the skeleton
|
||||||
*/
|
*/
|
||||||
@ -302,7 +331,8 @@ void
|
|||||||
makeenv(void)
|
makeenv(void)
|
||||||
{
|
{
|
||||||
FILE *ifp, *ofp;
|
FILE *ifp, *ofp;
|
||||||
char line[BUFSIZ], result[BUFSIZ], *linep;
|
nvlist_t *nvl;
|
||||||
|
char line[BUFSIZ];
|
||||||
struct envvar *envvar;
|
struct envvar *envvar;
|
||||||
|
|
||||||
ofp = fopen(path("env.c.new"), "w");
|
ofp = fopen(path("env.c.new"), "w");
|
||||||
@ -312,27 +342,20 @@ makeenv(void)
|
|||||||
fprintf(ofp, "#include <sys/systm.h>\n");
|
fprintf(ofp, "#include <sys/systm.h>\n");
|
||||||
fprintf(ofp, "\n");
|
fprintf(ofp, "\n");
|
||||||
fprintf(ofp, "char static_env[] = {\n");
|
fprintf(ofp, "char static_env[] = {\n");
|
||||||
|
nvl = nvlist_create(0);
|
||||||
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
|
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
|
||||||
if (envvar->env_is_file) {
|
if (envvar->env_is_file) {
|
||||||
ifp = fopen(envvar->env_str, "r");
|
ifp = fopen(envvar->env_str, "r");
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
err(1, "%s", envvar->env_str);
|
err(1, "%s", envvar->env_str);
|
||||||
while (fgets(line, BUFSIZ, ifp) != NULL) {
|
while (fgets(line, BUFSIZ, ifp) != NULL)
|
||||||
sanitize_envline(result, line);
|
process_into_nvlist(line, nvl);
|
||||||
/* anything left? */
|
dump_nvlist(nvl, ofp);
|
||||||
if (*result == '\0')
|
|
||||||
continue;
|
|
||||||
fprintf(ofp, "\"%s\\0\"\n", result);
|
|
||||||
}
|
|
||||||
fclose(ifp);
|
fclose(ifp);
|
||||||
} else {
|
} else
|
||||||
linep = envvar->env_str;
|
process_into_file(envvar->env_str, ofp);
|
||||||
sanitize_envline(result, linep);
|
|
||||||
if (*result == '\0')
|
|
||||||
continue;
|
|
||||||
fprintf(ofp, "\"%s\\0\"\n", result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
nvlist_destroy(nvl);
|
||||||
fprintf(ofp, "\"\\0\"\n};\n");
|
fprintf(ofp, "\"\\0\"\n};\n");
|
||||||
fclose(ofp);
|
fclose(ofp);
|
||||||
moveifchanged(path("env.c.new"), path("env.c"));
|
moveifchanged(path("env.c.new"), path("env.c"));
|
||||||
|
Loading…
Reference in New Issue
Block a user