Let config extract embedded configuration data from kernels that were built
with either "options INCLUDE_CONFIG_FILE" or "options INCLUDE_JUST_CONFIG". The program can now be invoked like: - config -b objdir -s srcdir /netbsd This will use configuration data from /netbsd to automatically create the build directory of the new kernel. - config -x /netbsd > CONFFILE This will store configuration data from /netbsd in the CONFFILE file for further editing.
This commit is contained in:
parent
325b10be64
commit
f37b7f38ab
|
@ -1,4 +1,4 @@
|
||||||
.\" $NetBSD: config.8,v 1.23 2003/04/24 13:23:55 jmmv Exp $
|
.\" $NetBSD: config.8,v 1.24 2003/04/26 12:53:43 jmmv Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 1980, 1991, 1993
|
.\" Copyright (c) 1980, 1991, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" from: @(#)config.8 8.2 (Berkeley) 4/19/94
|
.\" from: @(#)config.8 8.2 (Berkeley) 4/19/94
|
||||||
.\"
|
.\"
|
||||||
.Dd April 19, 1994
|
.Dd April 26, 2003
|
||||||
.Dt CONFIG 8
|
.Dt CONFIG 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -45,7 +45,11 @@
|
||||||
.Op Fl b Ar builddir
|
.Op Fl b Ar builddir
|
||||||
.Op Fl s Ar srcdir
|
.Op Fl s Ar srcdir
|
||||||
.Op Ar config-file
|
.Op Ar config-file
|
||||||
|
.Nm
|
||||||
|
.Fl x
|
||||||
|
.Op Ar kernel-file
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
In its first synopsis form,
|
||||||
.Nm
|
.Nm
|
||||||
creates a kernel build directory from the machine description file
|
creates a kernel build directory from the machine description file
|
||||||
.Ar config-file ,
|
.Ar config-file ,
|
||||||
|
@ -109,6 +113,21 @@ directive at the beginning of the machine description file.
|
||||||
You must specify the location of the top-level kernel source directory if you
|
You must specify the location of the top-level kernel source directory if you
|
||||||
specify a build directory.
|
specify a build directory.
|
||||||
.Pp
|
.Pp
|
||||||
|
If
|
||||||
|
.Ar config-file
|
||||||
|
is a binary kernel,
|
||||||
|
.Nm
|
||||||
|
will try to extract the configuration file embedded into it, which will
|
||||||
|
be present if that kernel was built either with
|
||||||
|
.Va INCLUDE_CONFIG_FILE
|
||||||
|
or
|
||||||
|
.Va INCLUDE_JUST_CONFIG
|
||||||
|
options.
|
||||||
|
This work mode requires you to manually specify a build directory with
|
||||||
|
the
|
||||||
|
.Fl b
|
||||||
|
option, which implies the need to provide a source tree too.
|
||||||
|
.Pp
|
||||||
If the
|
If the
|
||||||
.Fl p
|
.Fl p
|
||||||
option is supplied,
|
option is supplied,
|
||||||
|
@ -183,6 +202,26 @@ if there are configuration errors,
|
||||||
but this code is not well-tested,
|
but this code is not well-tested,
|
||||||
and some problems (such as running out of disk space)
|
and some problems (such as running out of disk space)
|
||||||
are unrecoverable.
|
are unrecoverable.
|
||||||
|
.Pp
|
||||||
|
In its second synopsis form,
|
||||||
|
.Nm
|
||||||
|
takes the binary kernel
|
||||||
|
.Ar kernel-file
|
||||||
|
as its single argument (aside from the mandatory
|
||||||
|
.Fl x
|
||||||
|
flag), then extracts the embedded configuration file (if any) and
|
||||||
|
writes it to standard output.
|
||||||
|
If
|
||||||
|
.Ar kernel-file
|
||||||
|
is not given,
|
||||||
|
.Pa /netbsd
|
||||||
|
is used.
|
||||||
|
Configuration data will be available if the given kernel was compiled
|
||||||
|
with either
|
||||||
|
.Va INCLUDE_CONFIG_FILE
|
||||||
|
or
|
||||||
|
.Va INCLUDE_JUST_CONFIG
|
||||||
|
options.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
The SYNOPSIS portion of each device in section 4.
|
The SYNOPSIS portion of each device in section 4.
|
||||||
.\".Rs
|
.\".Rs
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: main.c,v 1.75 2003/01/27 05:00:54 thorpej Exp $ */
|
/* $NetBSD: main.c,v 1.76 2003/04/26 12:53:43 jmmv Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1992, 1993
|
* Copyright (c) 1992, 1993
|
||||||
|
@ -59,9 +59,12 @@ COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -70,6 +73,10 @@ COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
||||||
#include "sem.h"
|
#include "sem.h"
|
||||||
#include <vis.h>
|
#include <vis.h>
|
||||||
|
|
||||||
|
#ifndef LINE_MAX
|
||||||
|
#define LINE_MAX 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
int vflag; /* verbose output */
|
int vflag; /* verbose output */
|
||||||
int Pflag; /* pack locators */
|
int Pflag; /* pack locators */
|
||||||
|
|
||||||
|
@ -110,6 +117,9 @@ static void logconfig_end(void);
|
||||||
static FILE *cfg;
|
static FILE *cfg;
|
||||||
static time_t cfgtime;
|
static time_t cfgtime;
|
||||||
|
|
||||||
|
static int is_elf(const char *);
|
||||||
|
static int extract_config(const char *, const char *, int);
|
||||||
|
|
||||||
int badfilename(const char *fname);
|
int badfilename(const char *fname);
|
||||||
|
|
||||||
const char *progname;
|
const char *progname;
|
||||||
|
@ -117,14 +127,15 @@ const char *progname;
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p, cname[20];
|
||||||
const char *last_component;
|
const char *last_component;
|
||||||
int pflag, ch;
|
int pflag, xflag, ch, removeit;
|
||||||
|
|
||||||
setprogname(argv[0]);
|
setprogname(argv[0]);
|
||||||
|
|
||||||
pflag = 0;
|
pflag = 0;
|
||||||
while ((ch = getopt(argc, argv, "DPgpvb:s:")) != -1) {
|
xflag = 0;
|
||||||
|
while ((ch = getopt(argc, argv, "DPgpvb:s:x")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
|
||||||
#ifndef MAKE_BOOTSTRAP
|
#ifndef MAKE_BOOTSTRAP
|
||||||
|
@ -175,6 +186,10 @@ main(int argc, char **argv)
|
||||||
srcdir = optarg;
|
srcdir = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
xflag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
goto usage;
|
goto usage;
|
||||||
|
@ -185,9 +200,34 @@ main(int argc, char **argv)
|
||||||
argv += optind;
|
argv += optind;
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
usage:
|
usage:
|
||||||
(void)fputs("usage: config [-Ppv] [-s srcdir] [-b builddir] sysname\n", stderr);
|
(void)fputs("usage: config [-Ppv] [-s srcdir] [-b builddir] "
|
||||||
|
"[sysname]\n", stderr);
|
||||||
|
(void)fputs(" config -x [kernel-file]\n", stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xflag && (builddir != NULL || srcdir != NULL || Pflag || pflag ||
|
||||||
|
vflag)) {
|
||||||
|
(void)fprintf(stderr, "config: -x must be used alone\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xflag) {
|
||||||
|
conffile = (argc == 1) ? argv[0] : _PATH_UNIX;
|
||||||
|
if (!is_elf(conffile)) {
|
||||||
|
(void)fprintf(stderr, "%s: not a binary kernel\n",
|
||||||
|
conffile);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!extract_config(conffile, "stdout", STDOUT_FILENO)) {
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
"config: %s does not contain embedded "
|
||||||
|
"configuration data\n", conffile);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
conffile = (argc == 1) ? argv[0] : "CONFIG";
|
conffile = (argc == 1) ? argv[0] : "CONFIG";
|
||||||
if (firstfile(conffile)) {
|
if (firstfile(conffile)) {
|
||||||
(void)fprintf(stderr, "config: cannot read %s: %s\n",
|
(void)fprintf(stderr, "config: cannot read %s: %s\n",
|
||||||
|
@ -242,6 +282,43 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
defbuilddir = (argc == 0) ? "." : p;
|
defbuilddir = (argc == 0) ? "." : p;
|
||||||
|
|
||||||
|
removeit = 0;
|
||||||
|
if (is_elf(conffile)) {
|
||||||
|
char *tmpdir;
|
||||||
|
int cfd;
|
||||||
|
|
||||||
|
if (builddir == NULL) {
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
"config: build directory must be specified with "
|
||||||
|
"binary kernels\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open temporary configuration file */
|
||||||
|
tmpdir = getenv("TMPDIR");
|
||||||
|
if (tmpdir == NULL)
|
||||||
|
tmpdir = "/tmp";
|
||||||
|
snprintf(cname, sizeof(cname), "%s/config.tmp.XXXXXX", tmpdir);
|
||||||
|
cfd = mkstemp(cname);
|
||||||
|
if (cfd == -1) {
|
||||||
|
fprintf(stderr, "config: cannot create %s: %s", cname,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Using configuration data embedded in kernel...\n");
|
||||||
|
if (!extract_config(conffile, cname, cfd)) {
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
"config: %s does not contain embedded "
|
||||||
|
"configuration data\n", conffile);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeit = 1;
|
||||||
|
close(cfd);
|
||||||
|
firstfile(cname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse config file (including machine definitions).
|
* Parse config file (including machine definitions).
|
||||||
*/
|
*/
|
||||||
|
@ -250,6 +327,9 @@ main(int argc, char **argv)
|
||||||
stop();
|
stop();
|
||||||
logconfig_end();
|
logconfig_end();
|
||||||
|
|
||||||
|
if (removeit)
|
||||||
|
unlink(cname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select devices and pseudo devices and their attributes
|
* Select devices and pseudo devices and their attributes
|
||||||
*/
|
*/
|
||||||
|
@ -1297,3 +1377,91 @@ strtolower(const char *name)
|
||||||
return (intern(low));
|
return (intern(low));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_elf(const char *file)
|
||||||
|
{
|
||||||
|
int kernel;
|
||||||
|
char hdr[4];
|
||||||
|
|
||||||
|
kernel = open(file, O_RDONLY);
|
||||||
|
if (kernel == -1) {
|
||||||
|
fprintf(stderr, "config: cannot open %s: %s\n", file,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (read(kernel, hdr, 4) == -1) {
|
||||||
|
fprintf(stderr, "config: cannot read from %s: %s\n", file,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
close(kernel);
|
||||||
|
|
||||||
|
return memcmp("\177ELF", hdr, 4) == 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
extract_config(const char *kname, const char *cname, int cfd)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int found, kfd, i;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
/* mmap(2) binary kernel */
|
||||||
|
kfd = open(conffile, O_RDONLY);
|
||||||
|
if (kfd == -1) {
|
||||||
|
fprintf(stderr, "config: cannot open %s: %s\n", kname,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if ((fstat(kfd, &st) == -1)) {
|
||||||
|
fprintf(stderr, "config: cannot stat %s: %s\n", kname,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
ptr = (char *)mmap(0, st.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
|
||||||
|
kfd, 0);
|
||||||
|
if (ptr == MAP_FAILED) {
|
||||||
|
fprintf(stderr, "config: cannot mmap %s: %s\n", kname,
|
||||||
|
strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan mmap(2)'ed region, extracting kernel configuration */
|
||||||
|
for (i = 0; i < st.st_size; i++) {
|
||||||
|
if ((*ptr == '_') && (st.st_size - i > 5) && memcmp(ptr,
|
||||||
|
"_CFG_", 5) == 0) {
|
||||||
|
/* Line found */
|
||||||
|
char *oldptr, line[LINE_MAX + 1], uline[LINE_MAX + 1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
oldptr = (ptr += 5);
|
||||||
|
while (*ptr != '\n' && *ptr != '\0') ptr++;
|
||||||
|
if (ptr - oldptr > LINE_MAX) {
|
||||||
|
fprintf(stderr, "config: line too long\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
memcpy(line, oldptr, (ptr - oldptr));
|
||||||
|
line[ptr - oldptr] = '\0';
|
||||||
|
i = strunvis(uline, line);
|
||||||
|
if (i == -1) {
|
||||||
|
fprintf(stderr, "config: unvis: invalid "
|
||||||
|
"encoded sequence\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
uline[i] = '\n';
|
||||||
|
if (write(cfd, uline, i + 1) == -1) {
|
||||||
|
fprintf(stderr, "config: cannot write to %s: "
|
||||||
|
"%s\n", cname, strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
} else ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(kfd);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue