summaryrefslogtreecommitdiff
path: root/usr.sbin/config
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/config')
-rw-r--r--usr.sbin/config/config.86
-rw-r--r--usr.sbin/config/config.h66
-rw-r--r--usr.sbin/config/files.c373
-rw-r--r--usr.sbin/config/gram.y69
-rw-r--r--usr.sbin/config/hash.c6
-rw-r--r--usr.sbin/config/main.c104
-rw-r--r--usr.sbin/config/mkheaders.c8
-rw-r--r--usr.sbin/config/mkioconf.c33
-rw-r--r--usr.sbin/config/mkmakefile.c60
-rw-r--r--usr.sbin/config/mkswap.c10
-rw-r--r--usr.sbin/config/pack.c6
-rw-r--r--usr.sbin/config/scan.l8
-rw-r--r--usr.sbin/config/sem.c326
-rw-r--r--usr.sbin/config/sem.h9
-rw-r--r--usr.sbin/config/util.c15
15 files changed, 804 insertions, 295 deletions
diff --git a/usr.sbin/config/config.8 b/usr.sbin/config/config.8
index b93276db33d..e8c8bac7e0b 100644
--- a/usr.sbin/config/config.8
+++ b/usr.sbin/config/config.8
@@ -1,5 +1,5 @@
-.\" $OpenBSD: config.8,v 1.2 1996/03/25 15:55:01 niklas Exp $
-.\" $NetBSD: config.8,v 1.8 1996/03/03 17:28:05 thorpej Exp $
+.\" $OpenBSD: config.8,v 1.3 1996/04/21 23:40:05 deraadt Exp $
+.\" $NetBSD: config.8,v 1.9 1996/03/17 06:29:19 cgd Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -53,7 +53,7 @@ program.
.\"used on the SPARC and i386 platforms.
.\"The old version of config is still used with the
.\"HP300, DECstation, and derivative platforms.
-.\"Only the version of
+.\"Only the version of
.\".Nm config
.\"applicable to the architecture that you are running
.\"will be installed on your machine.
diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h
index 116503b51a8..178c6923741 100644
--- a/usr.sbin/config/config.h
+++ b/usr.sbin/config/config.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: config.h,v 1.2 1996/03/25 15:55:02 niklas Exp $ */
-/* $NetBSD: config.h,v 1.19 1996/03/03 17:28:08 thorpej Exp $ */
+/* $OpenBSD: config.h,v 1.3 1996/04/21 23:40:07 deraadt Exp $ */
+/* $NetBSD: config.h,v 1.23 1996/03/17 13:18:15 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -94,19 +94,27 @@ struct attr {
};
/*
- * The "base" part of a device ("uba", "sd"; but not "uba2" or
- * "sd0"). It may be found "at" one or more attributes, including
- * "at root" (this is represented by a NULL attribute).
+ * The "base" part (struct devbase) of a device ("uba", "sd"; but not
+ * "uba2" or "sd0"). It may be found "at" one or more attributes,
+ * including "at root" (this is represented by a NULL attribute), as
+ * specified by the device attachments (struct deva).
*
* Each device may also export attributes. If any provide an output
* interface (e.g., "esp" provides "scsi"), other devices (e.g.,
* "tg"s) can be found at instances of this one (e.g., "esp"s).
* Such a connection must provide locators as specified by that
- * interface attribute (e.g., "target").
+ * interface attribute (e.g., "target"). The base device can
+ * export both output (aka `interface') attributes, as well as
+ * import input (`plain') attributes. Device attachments may
+ * only import input attributes; it makes no sense to have a
+ * specific attachment export a new interface to other devices.
*
* Each base carries a list of instances (via d_ihead). Note that this
* list "skips over" aliases; those must be found through the instances
- * themselves.
+ * themselves. Each base also carries a list of possible attachments,
+ * each of which specify a set of devices that the device can attach
+ * to, as well as the device instances that are actually using that
+ * attachment.
*/
struct devbase {
const char *d_name; /* e.g., "sd" */
@@ -114,12 +122,25 @@ struct devbase {
int d_isdef; /* set once properly defined */
int d_ispseudo; /* is a pseudo-device */
int d_major; /* used for "root on sd0", e.g. */
+ struct nvlist *d_attrs; /* attributes, if any */
+ int d_umax; /* highest unit number + 1 */
+ struct devi *d_ihead; /* first instance, if any */
+ struct devi **d_ipp; /* used for tacking on more instances */
+ struct deva *d_ahead; /* first attachment, if any */
+ struct deva **d_app; /* used for tacking on attachments */
+};
+
+struct deva {
+ const char *d_name; /* name of attachment, e.g. "com_isa" */
+ struct deva *d_next; /* linked list */
+ struct deva *d_bsame; /* list on same base */
+ int d_isdef; /* set once properly defined */
+ struct devbase *d_devbase; /* the base device */
struct nvlist *d_atlist; /* e.g., "at tg" (attr list) */
struct nvlist *d_vectors; /* interrupt vectors, if any */
struct nvlist *d_attrs; /* attributes, if any */
struct devi *d_ihead; /* first instance, if any */
struct devi **d_ipp; /* used for tacking on more instances */
- int d_umax; /* highest unit number + 1 */
};
/*
@@ -139,10 +160,12 @@ struct devi {
struct devbase *i_base;/* e.g., pointer to "sd" base */
struct devi *i_next; /* list of all instances */
struct devi *i_bsame; /* list on same base */
+ struct devi *i_asame; /* list on same base attachment */
struct devi *i_alias; /* other aliases of this instance */
const char *i_at; /* where this is "at" (NULL if at root) */
struct attr *i_atattr; /* attr that allowed attach */
- struct devbase *i_atdev;/* dev if "at <devname><unit>", else NULL */
+ struct devbase *i_atdev;/* if "at <devname><unit>", else NULL */
+ struct deva *i_atdeva;
const char **i_locs; /* locators (as given by i_atattr) */
int i_atunit; /* unit from "at" */
int i_cfflags; /* flags from config line */
@@ -165,7 +188,16 @@ struct devi {
/*
* Files. Each file is either standard (always included) or optional,
- * depending on whether it has names on which to *be* optional.
+ * depending on whether it has names on which to *be* optional. The
+ * options field (fi_optx) is actually an expression tree, with nodes
+ * for OR, AND, and NOT, as well as atoms (words) representing some
+ * particular option. The node type is stored in the nv_int field.
+ * Subexpressions appear in the `next' field; for the binary operators
+ * AND and OR, the left subexpression is first stored in the nv_ptr field.
+ *
+ * For any file marked as needs-count or needs-flag, fixfiles() will
+ * build fi_optf, a `flat list' of the options with nv_int fields that
+ * contain counts or `need' flags; this is used in mkheaders().
*/
struct files {
struct files *fi_next; /* linked list */
@@ -176,9 +208,14 @@ struct files {
const char *fi_path; /* full file path */
const char *fi_tail; /* name, i.e., rindex(fi_path, '/') + 1 */
const char *fi_base; /* tail minus ".c" (or whatever) */
- struct nvlist *fi_opt; /* optional on ... */
+ struct nvlist *fi_optx;/* options expression */
+ struct nvlist *fi_optf;/* flattened version of above, if needed */
const char *fi_mkrule; /* special make rule, if any */
};
+#define FX_ATOM 0 /* atom (in nv_name) */
+#define FX_NOT 1 /* NOT expr (subexpression in nv_next) */
+#define FX_AND 2 /* AND expr (lhs in nv_ptr, rhs in nv_next) */
+#define FX_OR 3 /* OR expr (lhs in nv_ptr, rhs in nv_next) */
/* flags */
#define FI_SEL 0x01 /* selected */
@@ -210,10 +247,12 @@ int maxpartitions; /* configuration's "maxpartitions" parameter */
struct nvlist *options; /* options */
struct nvlist *mkoptions; /* makeoptions */
struct hashtab *devbasetab; /* devbase lookup */
+struct hashtab *devatab; /* devbase attachment lookup */
struct hashtab *selecttab; /* selects things that are "optional foo" */
struct hashtab *needcnttab; /* retains names marked "needs-count" */
struct devbase *allbases; /* list of all devbase structures */
+struct deva *alldevas; /* list of all devbase attachment structures */
struct config *allcf; /* list of configured kernels */
struct devi *alldevi; /* list of all instances */
struct devi *allpseudo; /* list of all pseudo-devices */
@@ -252,6 +291,8 @@ const char *intern __P((const char *));
/* main.c */
void addoption __P((const char *name, const char *value));
void addmkoption __P((const char *name, const char *value));
+int devbase_has_instances __P((struct devbase *, int));
+int deva_has_instances __P((struct deva *, int));
/* mkheaders.c */
int mkheaders __P((void));
@@ -281,6 +322,7 @@ char *path __P((const char *));
void error __P((const char *, ...)); /* immediate errs */
void xerror __P((const char *, int, const char *, ...)); /* delayed errs */
__dead void panic __P((const char *, ...));
-struct nvlist *newnv __P((const char *, const char *, void *, int));
+struct nvlist *newnv __P((const char *, const char *, void *, int,
+ struct nvlist *));
void nvfree __P((struct nvlist *));
void nvfreel __P((struct nvlist *));
diff --git a/usr.sbin/config/files.c b/usr.sbin/config/files.c
index 61574f5b004..ac2f302cf51 100644
--- a/usr.sbin/config/files.c
+++ b/usr.sbin/config/files.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: files.c,v 1.3 1996/03/25 15:55:03 niklas Exp $ */
-/* $NetBSD: files.c,v 1.3 1996/03/03 17:28:10 thorpej Exp $ */
+/* $OpenBSD: files.c,v 1.4 1996/04/21 23:40:09 deraadt Exp $ */
+/* $NetBSD: files.c,v 1.6 1996/03/17 13:18:17 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -66,6 +66,14 @@ static struct hashtab *pathtab; /* full path names */
static struct files **nextfile;
static struct files **unchecked;
+static int checkaux __P((const char *, void *));
+static int fixcount __P((const char *, void *));
+static int fixfsel __P((const char *, void *));
+static int fixsel __P((const char *, void *));
+static int expr_eval __P((struct nvlist *,
+ int (*)(const char *, void *), void *));
+static void expr_free __P((struct nvlist *));
+
void
initfiles()
{
@@ -88,17 +96,17 @@ showprev(pref, fi)
}
void
-addfile(path, opts, flags, rule)
+addfile(path, optx, flags, rule)
const char *path;
- struct nvlist *opts;
+ struct nvlist *optx;
int flags;
const char *rule;
{
struct files *fi;
- const char *base, *dotp, *tail;
+ const char *dotp, *tail;
size_t baselen;
int needc, needf;
- char buf[200];
+ char base[200];
/* check various errors */
needc = flags & FI_NEEDSCOUNT;
@@ -107,15 +115,10 @@ addfile(path, opts, flags, rule)
error("cannot mix needs-count and needs-flag");
goto bad;
}
- if (opts == NULL && (needc || needf)) {
+ if (optx == NULL && (needc || needf)) {
error("nothing to %s for %s", needc ? "count" : "flag", path);
goto bad;
}
- if ((fi = ht_lookup(pathtab, path)) != NULL) {
- showprev("", fi);
- error("file %s listed again", path);
- goto bad;
- }
/* find last part of pathname, and same without trailing suffix */
tail = rindex(path, '/');
@@ -125,57 +128,41 @@ addfile(path, opts, flags, rule)
tail++;
dotp = rindex(tail, '.');
if (dotp == NULL || dotp[1] == 0 ||
- (baselen = dotp - tail) >= sizeof(buf)) {
+ (baselen = dotp - tail) >= sizeof(base)) {
error("invalid pathname `%s'", path);
goto bad;
}
/*
- * Make a copy of the path without the .c/.s/whatever suffix.
- * This must be unique per "files" file (e.g., a specific
- * file can override a standard file, but no standard file
- * can override another standard file). This is not perfect
- * but should catch any major errors.
- */
- bcopy(tail, buf, baselen);
- buf[baselen] = 0;
- base = intern(buf);
- if ((fi = ht_lookup(basetab, base)) != NULL) {
- if (fi->fi_srcfile != yyfile) {
- showprev("note: ", fi);
- error("is overridden by %s", path);
- errors--; /* take it away */
- fi->fi_flags |= FI_HIDDEN;
- } else {
- showprev("", fi);
- error("collides with %s (both make %s.o)",
- path, base);
- goto bad;
- }
- }
-
- /*
- * Commit this file to memory.
+ * Commit this file to memory. We will decide later whether it
+ * will be used after all.
*/
fi = emalloc(sizeof *fi);
+ if (ht_insert(pathtab, path, fi)) {
+ free(fi);
+ if ((fi = ht_lookup(pathtab, path)) == NULL)
+ panic("addfile: ht_lookup(%s)", path);
+ error("duplicate file %s", path);
+ xerror(fi->fi_srcfile, fi->fi_srcline,
+ "here is the original definition");
+ }
+ memcpy(base, tail, baselen);
+ base[baselen] = 0;
fi->fi_next = NULL;
fi->fi_srcfile = yyfile;
fi->fi_srcline = currentline();
fi->fi_flags = flags;
- fi->fi_lastc = dotp[strlen(dotp) - 1];
fi->fi_path = path;
fi->fi_tail = tail;
- fi->fi_base = base;
- fi->fi_opt = opts;
+ fi->fi_base = intern(base);
+ fi->fi_optx = optx;
+ fi->fi_optf = NULL;
fi->fi_mkrule = rule;
- if (ht_insert(pathtab, path, fi))
- panic("addfile: ht_insert(%s)", path);
- (void)ht_replace(basetab, base, fi);
*nextfile = fi;
nextfile = &fi->fi_next;
return;
bad:
- nvfreel(opts);
+ expr_free(optx);
}
/*
@@ -191,75 +178,265 @@ checkfiles()
register struct nvlist *nv;
last = NULL;
- for (fi = *unchecked; fi != NULL; last = fi, fi = fi->fi_next) {
- if ((fi->fi_flags & FI_NEEDSCOUNT) == 0)
- continue;
- for (nv = fi->fi_opt; nv != NULL; nv = nv->nv_next)
- if (ht_lookup(devbasetab, nv->nv_name) == NULL) {
- xerror(fi->fi_srcfile, fi->fi_srcline,
- "`%s' is not a countable device",
- nv->nv_name);
- /* keep fixfiles() from complaining again */
- fi->fi_flags |= FI_HIDDEN;
- }
- }
+ for (fi = *unchecked; fi != NULL; last = fi, fi = fi->fi_next)
+ if ((fi->fi_flags & FI_NEEDSCOUNT) != 0)
+ (void)expr_eval(fi->fi_optx, checkaux, fi);
if (last != NULL)
unchecked = &last->fi_next;
}
/*
+ * Auxiliary function for checkfiles, called from expr_eval.
+ * We are not actually interested in the expression's value.
+ */
+static int
+checkaux(name, context)
+ const char *name;
+ void *context;
+{
+ register struct files *fi = context;
+
+ if (ht_lookup(devbasetab, name) == NULL) {
+ xerror(fi->fi_srcfile, fi->fi_srcline,
+ "`%s' is not a countable device",
+ name);
+ /* keep fixfiles() from complaining again */
+ fi->fi_flags |= FI_HIDDEN;
+ }
+ return (0);
+}
+
+/*
* We have finished reading everything. Tack the files down: calculate
- * selection and counts as needed.
+ * selection and counts as needed. Check that the object files built
+ * from the selected sources do not collide.
*/
int
fixfiles()
{
- register struct files *fi;
- register struct nvlist *nv;
- register struct devbase *dev;
- int sel, err;
+ register struct files *fi, *ofi;
+ struct nvlist *flathead, **flatp;
+ int err, sel;
err = 0;
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
+ /* Skip files that generated counted-device complaints. */
if (fi->fi_flags & FI_HIDDEN)
continue;
- if ((nv = fi->fi_opt) == NULL) { /* standard */
- fi->fi_flags |= FI_SEL;
- continue;
+ if (fi->fi_optx != NULL) {
+ /* Optional: see if it is to be included. */
+ flathead = NULL;
+ flatp = &flathead;
+ sel = expr_eval(fi->fi_optx,
+ fi->fi_flags & FI_NEEDSCOUNT ? fixcount :
+ fi->fi_flags & FI_NEEDSFLAG ? fixfsel :
+ fixsel,
+ &flatp);
+ fi->fi_optf = flathead;
+ if (!sel)
+ continue;
}
- /* figure out whether it is selected */
- sel = 0;
- if (fi->fi_flags & FI_NEEDSCOUNT) {
- /* ... and compute counts too */
- do {
- dev = ht_lookup(devbasetab, nv->nv_name);
- if (dev == NULL) {
- xerror(fi->fi_srcfile, fi->fi_srcline,
- "`%s' is not a countable device",
- nv->nv_name);
- err = 1;
- } else {
- if (dev->d_umax)
- sel = 1;
- nv->nv_int = dev->d_umax;
- (void)ht_insert(needcnttab,
- nv->nv_name, nv);
- }
- } while ((nv = nv->nv_next) != NULL);
- } else {
- do {
- if (ht_lookup(selecttab, nv->nv_name)) {
- sel = 1;
- break;
- }
- } while ((nv = nv->nv_next) != NULL);
- if (fi->fi_flags & FI_NEEDSFLAG)
- for (nv = fi->fi_opt; nv; nv = nv->nv_next)
- nv->nv_int = sel;
+
+ /* We like this file. Make sure it generates a unique .o. */
+ if (ht_insert(basetab, fi->fi_base, fi)) {
+ if ((ofi = ht_lookup(basetab, fi->fi_base)) == NULL)
+ panic("fixfiles ht_lookup(%s)", fi->fi_base);
+ /*
+ * If the new file comes from a different source,
+ * allow the new one to override the old one.
+ */
+ if (fi->fi_path != ofi->fi_path) {
+ if (ht_replace(basetab, fi->fi_base, fi) != 1)
+ panic("fixfiles ht_replace(%s)",
+ fi->fi_base);
+ ofi->fi_flags &= ~FI_SEL;
+ ofi->fi_flags |= FI_HIDDEN;
+ } else {
+ xerror(fi->fi_srcfile, fi->fi_srcline,
+ "object file collision on %s.o, from %s",
+ fi->fi_base, fi->fi_path);
+ xerror(ofi->fi_srcfile, ofi->fi_srcline,
+ "here is the previous file: %s",
+ ofi->fi_path);
+ err = 1;
+ }
}
- /* if selected, we are go */
- if (sel)
- fi->fi_flags |= FI_SEL;
+ fi->fi_flags |= FI_SEL;
}
return (err);
}
+
+/*
+ * Called when evaluating a needs-count expression. Make sure the
+ * atom is a countable device. The expression succeeds iff there
+ * is at least one of them (note that while `xx*' will not always
+ * set xx's d_umax > 0, you cannot mix '*' and needs-count). The
+ * mkheaders() routine wants a flattened, in-order list of the
+ * atoms for `#define name value' lines, so we build that as we
+ * are called to eval each atom.
+ */
+static int
+fixcount(name, context)
+ register const char *name;
+ void *context;
+{
+ register struct nvlist ***p = context;
+ register struct devbase *dev;
+ register struct nvlist *nv;
+
+ dev = ht_lookup(devbasetab, name);
+ if (dev == NULL) /* cannot occur here; we checked earlier */
+ panic("fixcount(%s)", name);
+ nv = newnv(name, NULL, NULL, dev->d_umax, NULL);
+ **p = nv;
+ *p = &nv->nv_next;
+ (void)ht_insert(needcnttab, name, nv);
+ return (dev->d_umax != 0);
+}
+
+/*
+ * Called from fixfiles when eval'ing a selection expression for a
+ * file that will generate a .h with flags. We will need the flat list.
+ */
+static int
+fixfsel(name, context)
+ const char *name;
+ void *context;
+{
+ register struct nvlist ***p = context;
+ register struct nvlist *nv;
+ register int sel;
+
+ sel = ht_lookup(selecttab, name) != NULL;
+ nv = newnv(name, NULL, NULL, sel, NULL);
+ **p = nv;
+ *p = &nv->nv_next;
+ return (sel);
+}
+
+/*
+ * As for fixfsel above, but we do not need the flat list.
+ */
+static int
+fixsel(name, context)
+ const char *name;
+ void *context;
+{
+
+ return (ht_lookup(selecttab, name) != NULL);
+}
+
+/*
+ * Eval an expression tree. Calls the given function on each node,
+ * passing it the given context & the name; return value is &/|/! of
+ * results of evaluating atoms.
+ *
+ * No short circuiting ever occurs. fn must return 0 or 1 (otherwise
+ * our mixing of C's bitwise & boolean here may give surprises).
+ */
+static int
+expr_eval(expr, fn, context)
+ register struct nvlist *expr;
+ register int (*fn) __P((const char *, void *));
+ register void *context;
+{
+ int lhs, rhs;
+
+ switch (expr->nv_int) {
+
+ case FX_ATOM:
+ return ((*fn)(expr->nv_name, context));
+
+ case FX_NOT:
+ return (!expr_eval(expr->nv_next, fn, context));
+
+ case FX_AND:
+ lhs = expr_eval(expr->nv_ptr, fn, context);
+ rhs = expr_eval(expr->nv_next, fn, context);
+ return (lhs & rhs);
+
+ case FX_OR:
+ lhs = expr_eval(expr->nv_ptr, fn, context);
+ rhs = expr_eval(expr->nv_next, fn, context);
+ return (lhs | rhs);
+ }
+ panic("expr_eval %d", expr->nv_int);
+ /* NOTREACHED */
+}
+
+/*
+ * Free an expression tree.
+ */
+static void
+expr_free(expr)
+ register struct nvlist *expr;
+{
+ register struct nvlist *rhs;
+
+ /* This loop traverses down the RHS of each subexpression. */
+ for (; expr != NULL; expr = rhs) {
+ switch (expr->nv_int) {
+
+ /* Atoms and !-exprs have no left hand side. */
+ case FX_ATOM:
+ case FX_NOT:
+ break;
+
+ /* For AND and OR nodes, free the LHS. */
+ case FX_AND:
+ case FX_OR:
+ expr_free(expr->nv_ptr);
+ break;
+
+ default:
+ panic("expr_free %d", expr->nv_int);
+ }
+ rhs = expr->nv_next;
+ nvfree(expr);
+ }
+}
+
+#ifdef DEBUG
+/*
+ * Print expression tree.
+ */
+void
+prexpr(expr)
+ struct nvlist *expr;
+{
+ static void pr0();
+
+ printf("expr =");
+ pr0(expr);
+ printf("\n");
+ (void)fflush(stdout);
+}
+
+static void
+pr0(e)
+ register struct nvlist *e;
+{
+
+ switch (e->nv_int) {
+ case FX_ATOM:
+ printf(" %s", e->nv_name);
+ return;
+ case FX_NOT:
+ printf(" (!");
+ break;
+ case FX_AND:
+ printf(" (&");
+ break;
+ case FX_OR:
+ printf(" (|");
+ break;
+ default:
+ printf(" (?%d?", e->nv_int);
+ break;
+ }
+ if (e->nv_ptr)
+ pr0(e->nv_ptr);
+ pr0(e->nv_next);
+ printf(")");
+}
+#endif
diff --git a/usr.sbin/config/gram.y b/usr.sbin/config/gram.y
index 3b197a85745..8d50756b2e3 100644
--- a/usr.sbin/config/gram.y
+++ b/usr.sbin/config/gram.y
@@ -1,6 +1,6 @@
%{
-/* $OpenBSD: gram.y,v 1.2 1996/03/25 15:55:04 niklas Exp $ */
-/* $NetBSD: gram.y,v 1.3 1996/03/03 17:28:13 thorpej Exp $ */
+/* $OpenBSD: gram.y,v 1.3 1996/04/21 23:40:11 deraadt Exp $ */
+/* $NetBSD: gram.y,v 1.7 1996/03/17 13:18:18 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -69,14 +69,21 @@ static struct config conf; /* at most one active at a time */
/* the following is used to recover nvlist space after errors */
static struct nvlist *alloc[1000];
static int adepth;
-#define new0(n,s,p,i) (alloc[adepth++] = newnv(n, s, p, i))
-#define new_n(n) new0(n, NULL, NULL, 0)
-#define new_ns(n, s) new0(n, s, NULL, 0)
-#define new_si(s, i) new0(NULL, s, NULL, i)
-#define new_nsi(n,s,i) new0(n, s, NULL, i)
-#define new_np(n, p) new0(n, NULL, p, 0)
-#define new_s(s) new0(NULL, s, NULL, 0)
-#define new_p(p) new0(NULL, NULL, p, 0)
+#define new0(n,s,p,i,x) (alloc[adepth++] = newnv(n, s, p, i, x))
+#define new_n(n) new0(n, NULL, NULL, 0, NULL)
+#define new_nx(n, x) new0(n, NULL, NULL, 0, x)
+#define new_ns(n, s) new0(n, s, NULL, 0, NULL)
+#define new_si(s, i) new0(NULL, s, NULL, i, NULL)
+#define new_nsi(n,s,i) new0(n, s, NULL, i, NULL)
+#define new_np(n, p) new0(n, NULL, p, 0, NULL)
+#define new_s(s) new0(NULL, s, NULL, 0, NULL)
+#define new_p(p) new0(NULL, NULL, p, 0, NULL)
+#define new_px(p, x) new0(NULL, NULL, p, 0, x)
+
+#define fx_atom(s) new0(s, NULL, NULL, FX_ATOM, NULL)
+#define fx_not(e) new0(NULL, NULL, NULL, FX_NOT, e)
+#define fx_and(e1, e2) new0(NULL, NULL, e1, FX_AND, e2)
+#define fx_or(e1, e2) new0(NULL, NULL, e1, FX_OR, e2)
static void cleanup __P((void));
static void setmachine __P((const char *, const char *));
@@ -87,22 +94,24 @@ static void setmaxpartitions __P((int));
%union {
struct attr *attr;
struct devbase *devb;
+ struct deva *deva;
struct nvlist *list;
const char *str;
int val;
}
-%token AND AT COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
+%token AND AT ATTACH COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS
-%token MINOR ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR
+%token MINOR ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR WITH
%token <val> FFLAG NUMBER
%token <str> PATHNAME WORD
-%type <list> fopts
+%type <list> fopts fexpr fatom
%type <val> fflgs
%type <str> rule
%type <attr> attr
%type <devb> devbase
+%type <deva> devattach_opt
%type <list> atlist interface_opt
%type <str> atname
%type <list> loclist_opt loclist locdef
@@ -164,9 +173,19 @@ file:
/* order of options is important, must use right recursion */
fopts:
- WORD fopts = { ($$ = new_n($1))->nv_next = $2; } |
+ fexpr = { $$ = $1; } |
/* empty */ = { $$ = NULL; };
+fexpr:
+ fatom = { $$ = $1; } |
+ '!' fatom = { $$ = fx_not($2); } |
+ fexpr '&' fexpr = { $$ = fx_and($1, $3); } |
+ fexpr '|' fexpr = { $$ = fx_or($1, $3); } |
+ '(' fexpr ')' = { $$ = $2; };
+
+fatom:
+ WORD = { $$ = fx_atom($1); };
+
fflgs:
fflgs FFLAG = { $$ = $1 | $2; } |
/* empty */ = { $$ = 0; };
@@ -194,14 +213,17 @@ one_def:
file |
include |
DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
- DEVICE devbase AT atlist veclist_opt interface_opt attrs_opt
- = { defdev($2, 0, $4, $5, $6, $7); } |
+ DEVICE devbase interface_opt attrs_opt
+ = { defdev($2, 0, $3, $4); } |
+ ATTACH devbase AT atlist veclist_opt devattach_opt attrs_opt
+ = { defdevattach($6, $2, $4, $5,
+ $7); } |
MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
- PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,NULL,NULL,$3); } |
+ PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,$3); } |
MAJOR '{' majorlist '}';
atlist:
- atlist ',' atname = { ($$ = new_n($3))->nv_next = $1; } |
+ atlist ',' atname = { $$ = new_nx($3, $1); } |
atname = { $$ = new_n($1); };
atname:
@@ -214,14 +236,18 @@ veclist_opt:
/* veclist order matters, must use right recursion */
veclist:
- WORD veclist = { ($$ = new_n($1))->nv_next = $2; } |
+ WORD veclist = { $$ = new_nx($1, $2); } |
WORD = { $$ = new_n($1); };
devbase:
WORD = { $$ = getdevbase($1); };
+devattach_opt:
+ WITH WORD = { $$ = getdevattach($2); } |
+ /* empty */ = { $$ = NULL; };
+
interface_opt:
- '{' loclist_opt '}' = { ($$ = new_n(""))->nv_next = $2; } |
+ '{' loclist_opt '}' = { $$ = new_nx("", $2); } |
/* empty */ = { $$ = NULL; };
loclist_opt:
@@ -257,7 +283,7 @@ attrs_opt:
/* empty */ = { $$ = NULL; };
attrs:
- attrs ',' attr = { ($$ = new_p($3))->nv_next = $1; } |
+ attrs ',' attr = { $$ = new_px($3, $1); } |
attr = { $$ = new_p($1); };
attr:
@@ -351,7 +377,6 @@ device_instance:
attachment:
ROOT = { $$ = NULL; } |
WORD '?' = { $$ = wildref($1); } |
- WORD '*' = { $$ = starref($1); } |
WORD = { $$ = $1; };
locators:
diff --git a/usr.sbin/config/hash.c b/usr.sbin/config/hash.c
index e1290fd9456..538b7a703ff 100644
--- a/usr.sbin/config/hash.c
+++ b/usr.sbin/config/hash.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: hash.c,v 1.2 1996/03/25 15:55:05 niklas Exp $ */
-/* $NetBSD: hash.c,v 1.2 1996/03/03 17:28:15 thorpej Exp $ */
+/* $OpenBSD: hash.c,v 1.3 1996/04/21 23:40:12 deraadt Exp $ */
+/* $NetBSD: hash.c,v 1.3 1996/03/17 13:18:20 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -262,6 +262,8 @@ ht_insrep(ht, nam, val, replace)
}
*hpp = hp = newhashent(nam, h);
hp->h_value = val;
+ if (++ht->ht_used > ht->ht_lim)
+ ht_expand(ht);
return (0);
}
diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
index 5a2539a6e5b..c0e4482d74a 100644
--- a/usr.sbin/config/main.c
+++ b/usr.sbin/config/main.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: main.c,v 1.3 1996/03/25 15:55:06 niklas Exp $ */
-/* $NetBSD: main.c,v 1.13 1996/03/03 17:28:17 thorpej Exp $ */
+/* $OpenBSD: main.c,v 1.4 1996/04/21 23:40:14 deraadt Exp $ */
+/* $NetBSD: main.c,v 1.17 1996/03/17 11:50:13 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -78,7 +78,6 @@ static int do_option __P((struct hashtab *, struct nvlist ***,
static int crosscheck __P((void));
static int badstar __P((void));
static int mksymlinks __P((void));
-static int has_instances __P((struct devbase *, int));
static int hasparent __P((struct devi *));
static int cfcrosscheck __P((struct config *, const char *, struct nvlist *));
@@ -150,6 +149,7 @@ usage:
initfiles();
initsem();
devbasetab = ht_new();
+ devatab = ht_new();
selecttab = ht_new();
needcnttab = ht_new();
opttab = ht_new();
@@ -323,7 +323,7 @@ do_option(ht, nppp, name, value, type)
register struct nvlist *nv;
/* assume it will work */
- nv = newnv(name, value, NULL, 0);
+ nv = newnv(name, value, NULL, 0, NULL);
if (ht_insert(ht, name, nv) == 0) {
**nppp = nv;
*nppp = &nv->nv_next;
@@ -343,23 +343,40 @@ do_option(ht, nppp, name, value, type)
/*
* Return true if there is at least one instance of the given unit
- * on the given base (or any units, if unit == WILD).
+ * on the given device attachment (or any units, if unit == WILD).
*/
-static int
-has_instances(dev, unit)
- register struct devbase *dev;
+int
+deva_has_instances(deva, unit)
+ register struct deva *deva;
int unit;
{
register struct devi *i;
if (unit == WILD)
- return (dev->d_ihead != NULL);
- for (i = dev->d_ihead; i != NULL; i = i->i_bsame)
+ return (deva->d_ihead != NULL);
+ for (i = deva->d_ihead; i != NULL; i = i->i_asame)
if (unit == i->i_unit)
return (1);
return (0);
}
+/*
+ * Return true if there is at least one instance of the given unit
+ * on the given base (or any units, if unit == WILD).
+ */
+int
+devbase_has_instances(dev, unit)
+ register struct devbase *dev;
+ int unit;
+{
+ register struct deva *da;
+
+ for (da = dev->d_ahead; da != NULL; da = da->d_bsame)
+ if (deva_has_instances(da, unit))
+ return (1);
+ return (0);
+}
+
static int
hasparent(i)
register struct devi *i;
@@ -367,11 +384,30 @@ hasparent(i)
register struct nvlist *nv;
int atunit = i->i_atunit;
- if (i->i_atdev != NULL && has_instances(i->i_atdev, atunit))
- return (1);
+ /*
+ * We determine whether or not a device has a parent in in one
+ * of two ways:
+ * (1) If a parent device was named in the config file,
+ * i.e. cases (2) and (3) in sem.c:adddev(), then
+ * we search its devbase for a matching unit number.
+ * (2) If the device was attach to an attribute, then we
+ * search all attributes the device can be attached to
+ * for parents (with appropriate unit numebrs) that
+ * may be able to attach the device.
+ */
+
+ /*
+ * Case (1): A parent was named. Either it's configured, or not.
+ */
+ if (i->i_atdev != NULL)
+ return (devbase_has_instances(i->i_atdev, atunit));
+
+ /*
+ * Case (2): No parent was named. Look for devs that provide the attr.
+ */
if (i->i_atattr != NULL)
for (nv = i->i_atattr->a_refs; nv != NULL; nv = nv->nv_next)
- if (has_instances(nv->nv_ptr, atunit))
+ if (devbase_has_instances(nv->nv_ptr, atunit))
return (1);
return (0);
}
@@ -384,7 +420,7 @@ cfcrosscheck(cf, what, nv)
{
register struct devbase *dev;
register struct devi *pd;
- int errs;
+ int errs, devminor;
for (errs = 0; nv != NULL; nv = nv->nv_next) {
if (nv->nv_name == NULL)
@@ -392,13 +428,15 @@ cfcrosscheck(cf, what, nv)
dev = ht_lookup(devbasetab, nv->nv_name);
if (dev == NULL)
panic("cfcrosscheck(%s)", nv->nv_name);
- if (has_instances(dev, STAR) ||
- has_instances(dev, minor(nv->nv_int) / maxpartitions))
+ devminor = minor(nv->nv_int) / maxpartitions;
+ if (devbase_has_instances(dev, devminor))
+ continue;
+ if (devbase_has_instances(dev, STAR) &&
+ devminor >= dev->d_umax)
continue;
for (pd = allpseudo; pd != NULL; pd = pd->i_next)
- if (pd->i_base == dev &&
- (minor(nv->nv_int) / maxpartitions) < dev->d_umax &&
- (minor(nv->nv_int) / maxpartitions) >= 0)
+ if (pd->i_base == dev && devminor < dev->d_umax &&
+ devminor >= 0)
goto loop;
(void)fprintf(stderr,
"%s%d: %s says %s on %s, but there's no %s\n",
@@ -429,11 +467,9 @@ crosscheck()
continue;
xerror(conffile, i->i_lineno,
"%s at %s is orphaned", i->i_name, i->i_at);
- if (i->i_atunit == WILD)
- (void)fprintf(stderr, " (no %s declared)\n",
- i->i_at);
- else
- (void)fprintf(stderr, " (no %s declared)\n", i->i_at);
+ (void)fprintf(stderr, " (%s %s declared)\n",
+ i->i_atunit == WILD ? "nothing matching" : "no",
+ i->i_at);
errs++;
}
if (allcf == NULL) {
@@ -452,21 +488,23 @@ crosscheck()
}
/*
- * Check to see if there is more than one *'d unit for any device,
- * or a *'d unit with a needs-count file.
+ * Check to see if there is a *'d unit with a needs-count file.
*/
int
badstar()
{
register struct devbase *d;
+ register struct deva *da;
register struct devi *i;
register int errs, n;
errs = 0;
for (d = allbases; d != NULL; d = d->d_next) {
- for (i = d->d_ihead; i != NULL; i = i->i_bsame)
- if (i->i_unit == STAR)
- goto foundstar;
+ for (da = d->d_ahead; da != NULL; da = da->d_bsame)
+ for (i = da->d_ihead; i != NULL; i = i->i_asame) {
+ if (i->i_unit == STAR)
+ goto foundstar;
+ }
continue;
foundstar:
if (ht_lookup(needcnttab, d->d_name)) {
@@ -481,12 +519,6 @@ badstar()
n++;
if (n < 1)
panic("badstar() n<1");
- if (n == 1)
- continue;
- (void)fprintf(stderr,
- "config: %d %s*'s in configuration; can only have 1\n",
- n, d->d_name);
- errs++;
}
return (errs);
}
diff --git a/usr.sbin/config/mkheaders.c b/usr.sbin/config/mkheaders.c
index 91ddb8c28ac..d158c209a22 100644
--- a/usr.sbin/config/mkheaders.c
+++ b/usr.sbin/config/mkheaders.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mkheaders.c,v 1.2 1996/03/25 15:55:07 niklas Exp $ */
-/* $NetBSD: mkheaders.c,v 1.8 1996/03/03 17:28:20 thorpej Exp $ */
+/* $OpenBSD: mkheaders.c,v 1.3 1996/04/21 23:40:15 deraadt Exp $ */
+/* $NetBSD: mkheaders.c,v 1.10 1996/03/17 13:18:21 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -69,7 +69,7 @@ mkheaders()
if (fi->fi_flags & FI_HIDDEN)
continue;
if (fi->fi_flags & (FI_NEEDSCOUNT | FI_NEEDSFLAG) &&
- emitcnt(fi->fi_opt))
+ emitcnt(fi->fi_optf))
return (1);
}
return (0);
diff --git a/usr.sbin/config/mkioconf.c b/usr.sbin/config/mkioconf.c
index 56c40015a2e..c9b418d6831 100644
--- a/usr.sbin/config/mkioconf.c
+++ b/usr.sbin/config/mkioconf.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mkioconf.c,v 1.2 1996/03/25 15:55:08 niklas Exp $ */
-/* $NetBSD: mkioconf.c,v 1.36 1996/03/03 17:28:23 thorpej Exp $ */
+/* $OpenBSD: mkioconf.c,v 1.3 1996/04/21 23:40:17 deraadt Exp $ */
+/* $NetBSD: mkioconf.c,v 1.38 1996/03/17 06:29:27 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -161,16 +161,25 @@ emitexterns(fp)
register FILE *fp;
{
register struct devbase *d;
+ register struct deva *da;
NEWLINE;
for (d = allbases; d != NULL; d = d->d_next) {
- if (d->d_ihead == NULL)
+ if (!devbase_has_instances(d, WILD))
continue;
- if (fprintf(fp, "extern struct cfdriver %scd;\n",
+ if (fprintf(fp, "extern struct cfdriver %s_cd;\n",
d->d_name) < 0)
return (1);
}
NEWLINE;
+ for (da = alldevas; da != NULL; da = da->d_next) {
+ if (!deva_has_instances(da, WILD))
+ continue;
+ if (fprintf(fp, "extern struct cfattach %s_ca;\n",
+ da->d_name) < 0)
+ return (1);
+ }
+ NEWLINE;
return (0);
}
@@ -216,7 +225,7 @@ emitcfdata(fp)
{
register struct devi **p, *i, **par;
register int unit, v;
- register const char *vs, *state, *basename;
+ register const char *vs, *state, *basename, *attachment;
register struct nvlist *nv;
register struct attr *a;
char *loc;
@@ -227,7 +236,7 @@ emitcfdata(fp)
#define STAR FSTATE_STAR\n\
\n\
struct cfdata cfdata[] = {\n\
-\t/* driver unit state loc flags parents ivstubs */\n") < 0)
+ /* attachment driver unit state loc flags parents ivstubs */\n") < 0)
return (1);
for (p = packed; (i = *p) != NULL; p++) {
/* the description */
@@ -251,6 +260,7 @@ struct cfdata cfdata[] = {\n\
/* then the actual defining line */
basename = i->i_base->d_name;
+ attachment = i->i_atdeva->d_name;
if (i->i_unit == STAR) {
unit = i->i_base->d_umax;
state = "STAR";
@@ -271,12 +281,13 @@ struct cfdata cfdata[] = {\n\
} else
loc = "loc";
if (fprintf(fp, "\
-\t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n",
+ {&%s_ca,%s&%s_cd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n",
+ attachment, strlen(attachment) < 6 ? "\t\t" : "\t",
basename, strlen(basename) < 3 ? "\t\t" : "\t", unit,
state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0)
return (1);
}
- return (fputs("\t{0}\n};\n", fp) < 0);
+ return (fputs(" {0}\n};\n", fp) < 0);
}
/*
@@ -346,7 +357,7 @@ emitvec(fp)
nvec = 0;
for (p = packed; (i = *p) != NULL; p++) {
- if ((head = i->i_base->d_vectors) == NULL)
+ if ((head = i->i_atdeva->d_vectors) == NULL)
continue;
if ((unit = i->i_unit) == STAR)
panic("emitvec unit==STAR");
@@ -366,7 +377,7 @@ emitvec(fp)
return (1);
nvec = 0;
for (p = packed; (i = *p) != NULL; p++) {
- if ((head = i->i_base->d_vectors) == NULL)
+ if ((head = i->i_atdeva->d_vectors) == NULL)
continue;
i->i_ivoff = nvec;
unit = i->i_unit;
diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c
index 237ea6c1a17..33a31571ace 100644
--- a/usr.sbin/config/mkmakefile.c
+++ b/usr.sbin/config/mkmakefile.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mkmakefile.c,v 1.2 1996/03/25 15:55:09 niklas Exp $ */
-/* $NetBSD: mkmakefile.c,v 1.27 1996/03/03 17:28:26 thorpej Exp $ */
+/* $OpenBSD: mkmakefile.c,v 1.3 1996/04/21 23:40:18 deraadt Exp $ */
+/* $NetBSD: mkmakefile.c,v 1.29 1996/03/17 13:18:23 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -53,15 +53,19 @@
#include <string.h>
#include "config.h"
#include "sem.h"
+
/*
* Make the Makefile.
*/
+static const char *srcpath __P((struct files *));
+
static int emitdefs __P((FILE *));
+static int emitfiles __P((FILE *, int));
+
static int emitobjs __P((FILE *));
static int emitcfiles __P((FILE *));
static int emitsfiles __P((FILE *));
-static int emitfiles __P((FILE *, int));
static int emitrules __P((FILE *));
static int emitload __P((FILE *));
@@ -142,6 +146,33 @@ bad:
return (1);
}
+/*
+ * Return (possibly in a static buffer) the name of the `source' for a
+ * file. If we have `options source', or if the file is marked `always
+ * source', this is always the path from the `file' line; otherwise we
+ * get the .o from the obj-directory.
+ */
+static const char *
+srcpath(fi)
+ register struct files *fi;
+{
+#if 1
+ /* Always have source, don't support object dirs for kernel builds. */
+ return (fi->fi_path);
+#else
+ static char buf[MAXPATHLEN];
+
+ if (have_source || (fi->fi_flags & FI_ALWAYSSRC) != 0)
+ return (fi->fi_path);
+ if (objpath == NULL) {
+ error("obj-directory not set");
+ return (NULL);
+ }
+ (void)snprintf(buf, sizeof buf, "%s/%s.o", objpath, fi->fi_base);
+ return (buf);
+#endif
+}
+
static int
emitdefs(fp)
register FILE *fp;
@@ -225,6 +256,7 @@ emitfiles(fp, suffix)
register struct files *fi;
register struct config *cf;
register int lpos, len, sp;
+ register const char *fpath;
char swapname[100];
if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
@@ -234,10 +266,12 @@ emitfiles(fp, suffix)
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
if ((fi->fi_flags & FI_SEL) == 0)
continue;
- len = strlen(fi->fi_path);
- if (fi->fi_path[len - 1] != suffix)
+ if ((fpath = srcpath(fi)) == NULL)
+ return (1);
+ len = strlen(fpath);
+ if (fpath[len - 1] != suffix)
continue;
- if (*fi->fi_path != '/')
+ if (*fpath != '/')
len += 3; /* "$S/" */
if (lpos + len > 72) {
if (fputs(" \\\n", fp) < 0)
@@ -245,8 +279,8 @@ emitfiles(fp, suffix)
sp = '\t';
lpos = 7;
}
- if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
- fi->fi_path) < 0)
+ if (fprintf(fp, "%c%s%s", sp, *fpath != '/' ? "$S/" : "",
+ fpath) < 0)
return (1);
lpos += len + 1;
sp = ' ';
@@ -291,19 +325,21 @@ emitrules(fp)
register FILE *fp;
{
register struct files *fi;
- register const char *cp;
+ register const char *cp, *fpath;
int ch;
char buf[200];
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
if ((fi->fi_flags & FI_SEL) == 0)
continue;
+ if ((fpath = srcpath(fi)) == NULL)
+ return (1);
if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
- *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
+ *fpath != '/' ? "$S/" : "", fpath) < 0)
return (1);
if ((cp = fi->fi_mkrule) == NULL) {
cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
- ch = fi->fi_lastc;
+ ch = fpath[strlen(fpath) - 1];
if (islower(ch))
ch = toupper(ch);
(void)sprintf(buf, "${%s_%c%s}", cp, ch,
diff --git a/usr.sbin/config/mkswap.c b/usr.sbin/config/mkswap.c
index 83e86bb106c..53171687799 100644
--- a/usr.sbin/config/mkswap.c
+++ b/usr.sbin/config/mkswap.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mkswap.c,v 1.2 1996/03/25 15:55:10 niklas Exp $ */
-/* $NetBSD: mkswap.c,v 1.2 1996/03/03 17:28:29 thorpej Exp $ */
+/* $OpenBSD: mkswap.c,v 1.3 1996/04/21 23:40:20 deraadt Exp $ */
+/* $NetBSD: mkswap.c,v 1.4 1996/03/17 20:36:25 christos Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -121,9 +121,9 @@ mkoneswap(cf)
goto wrerror;
mountroot =
cf->cf_root->nv_str == s_nfs ? "nfs_mountroot" : "ffs_mountroot";
- if (fprintf(fp, "extern int %s();\n", mountroot) < 0)
+ if (fprintf(fp, "extern int %s __P((void *));\n", mountroot) < 0)
goto wrerror;
- if (fprintf(fp, "int (*mountroot)() = %s;\n", mountroot) < 0)
+ if (fprintf(fp, "int (*mountroot) __P((void *)) = %s;\n", mountroot) < 0)
goto wrerror;
if (fclose(fp)) {
diff --git a/usr.sbin/config/pack.c b/usr.sbin/config/pack.c
index 9e0b6330004..c3378c0c8b1 100644
--- a/usr.sbin/config/pack.c
+++ b/usr.sbin/config/pack.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: pack.c,v 1.2 1996/03/25 15:55:11 niklas Exp $ */
-/* $NetBSD: pack.c,v 1.2 1996/03/03 17:28:32 thorpej Exp $ */
+/* $OpenBSD: pack.c,v 1.3 1996/04/21 23:40:21 deraadt Exp $ */
+/* $NetBSD: pack.c,v 1.3 1996/03/17 06:29:33 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
diff --git a/usr.sbin/config/scan.l b/usr.sbin/config/scan.l
index 9f211c640b1..d79648c34d7 100644
--- a/usr.sbin/config/scan.l
+++ b/usr.sbin/config/scan.l
@@ -1,8 +1,8 @@
%{
-/* $OpenBSD: scan.l,v 1.2 1996/03/25 15:55:12 niklas Exp $ */
-/* $NetBSD: scan.l,v 1.2 1996/03/03 17:28:34 thorpej Exp $ */
+/* $OpenBSD: scan.l,v 1.3 1996/04/21 23:40:23 deraadt Exp $ */
+/* $NetBSD: scan.l,v 1.4 1996/03/17 06:29:35 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -87,6 +87,7 @@ WORD [A-Za-z_][-A-Za-z_0-9]*
/* plain keywords */
and { return AND; }
at { return AT; }
+attach { return ATTACH; }
compile-with { return COMPILE_WITH; }
config { return CONFIG; }
define { return DEFINE; }
@@ -107,6 +108,7 @@ options { return OPTIONS; }
root { return ROOT; }
swap { return SWAP; }
vector { return VECTOR; }
+with { return WITH; }
/* keywords with values */
config-dependent { yylval.val = FI_CONFIGDEP; return FFLAG; }
diff --git a/usr.sbin/config/sem.c b/usr.sbin/config/sem.c
index d0a69b5bfb1..cdd67f47e42 100644
--- a/usr.sbin/config/sem.c
+++ b/usr.sbin/config/sem.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: sem.c,v 1.2 1996/03/25 15:55:13 niklas Exp $ */
-/* $NetBSD: sem.c,v 1.2 1996/03/03 17:28:37 thorpej Exp $ */
+/* $OpenBSD: sem.c,v 1.3 1996/04/21 23:40:25 deraadt Exp $ */
+/* $NetBSD: sem.c,v 1.8 1996/03/17 21:12:03 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -69,7 +69,9 @@ static struct hashtab *devitab; /* etc */
static struct attr errattr;
static struct devbase errdev;
+static struct deva errdeva;
static struct devbase **nextbase;
+static struct deva **nextdeva;
static struct config **nextcf;
static struct devi **nextdevi;
static struct devi **nextpseudo;
@@ -85,7 +87,7 @@ static struct devi *newdevi __P((const char *, int, struct devbase *d));
static struct devi *getdevi __P((const char *));
static const char *concat __P((const char *, int));
static int split __P((const char *, size_t, char *, size_t, int *));
-static void selectbase __P((struct devbase *));
+static void selectbase __P((struct devbase *, struct deva *));
static int onlist __P((struct nvlist *, void *));
static const char **fixloc __P((const char *, struct attr *, struct nvlist *));
@@ -99,6 +101,9 @@ initsem()
allbases = NULL;
nextbase = &allbases;
+ alldevas = NULL;
+ nextdeva = &alldevas;
+
cfhashtab = ht_new();
allcf = NULL;
nextcf = &allcf;
@@ -238,21 +243,19 @@ addtoattr(l, dev)
{
register struct nvlist *n;
- n = newnv(NULL, NULL, dev, 0);
- n->nv_next = l;
+ n = newnv(NULL, NULL, dev, 0, l);
return (n);
}
/*
- * Device a device, giving its allowable parent attachments, if any.
- * This may (or may not) also define an interface attribute and/or refer
- * to existing attributes. There may be a list of vectors.
+ * Define a device. This may (or may not) also define an interface
+ * attribute and/or refer to existing attributes.
*/
void
-defdev(dev, ispseudo, atlist, vectors, loclist, attrs)
+defdev(dev, ispseudo, loclist, attrs)
register struct devbase *dev;
int ispseudo;
- struct nvlist *atlist, *vectors, *loclist, *attrs;
+ struct nvlist *loclist, *attrs;
{
register struct nvlist *nv;
register struct attr *a;
@@ -278,40 +281,15 @@ defdev(dev, ispseudo, atlist, vectors, loclist, attrs)
loclist = NULL; /* defattr disposes of them for us */
if (defattr(dev->d_name, nv))
goto bad;
- nv = newnv(dev->d_name, NULL, getattr(dev->d_name), 0);
- nv->nv_next = attrs;
- attrs = nv;
+ attrs = newnv(dev->d_name, NULL, getattr(dev->d_name), 0,
+ attrs);
}
/* Committed! Set up fields. */
dev->d_ispseudo = ispseudo;
- dev->d_atlist = atlist;
- dev->d_vectors = vectors;
dev->d_attrs = attrs;
/*
- * Turn the `at' list into interface attributes (map each
- * nv_name to an attribute, or to NULL for root), and add
- * this device to those attributes, so that children can
- * be listed at this particular device if they are supported
- * by that attribute.
- */
- for (nv = atlist; nv != NULL; nv = nv->nv_next) {
- if (nv->nv_name == NULL) {
- nv->nv_ptr = NULL; /* at root */
- continue;
- }
- nv->nv_ptr = a = getattr(nv->nv_name);
- if (a == &errattr)
- continue; /* already complained */
- if (!a->a_iattr)
- error("%s cannot be at plain attribute `%s'",
- dev->d_name, a->a_name);
- else
- a->a_devs = addtoattr(a->a_devs, dev);
- }
-
- /*
* For each interface attribute this device refers to, add this
* device to its reference list. This makes, e.g., finding all
* "scsi"s easier.
@@ -323,8 +301,6 @@ defdev(dev, ispseudo, atlist, vectors, loclist, attrs)
}
return;
bad:
- nvfreel(atlist);
- nvfreel(vectors);
nvfreel(loclist);
nvfreel(attrs);
}
@@ -359,11 +335,11 @@ badname:
dev->d_next = NULL;
dev->d_isdef = 0;
dev->d_major = NODEV;
- dev->d_atlist = NULL;
- dev->d_vectors = NULL;
dev->d_attrs = NULL;
dev->d_ihead = NULL;
dev->d_ipp = &dev->d_ihead;
+ dev->d_ahead = NULL;
+ dev->d_app = &dev->d_ahead;
dev->d_umax = 0;
*nextbase = dev;
nextbase = &dev->d_next;
@@ -374,6 +350,143 @@ badname:
}
/*
+ * Define some of a device's allowable parent attachments.
+ * There may be a list of vectors and a list of (plain) attributes.
+ */
+void
+defdevattach(deva, dev, atlist, vectors, attrs)
+ register struct deva *deva;
+ struct devbase *dev;
+ struct nvlist *atlist, *vectors, *attrs;
+{
+ register struct nvlist *nv;
+ register struct attr *a;
+ register struct deva *da;
+
+ if (dev == &errdev)
+ goto bad;
+ if (deva == NULL)
+ deva = getdevattach(dev->d_name);
+ if (deva == &errdeva)
+ goto bad;
+ if (!dev->d_isdef) {
+ error("attaching undefined device `%s'", dev->d_name);
+ goto bad;
+ }
+ if (deva->d_isdef) {
+ error("redefinition of `%s'", deva->d_name);
+ goto bad;
+ }
+ if (dev->d_ispseudo) {
+ error("pseudo-devices can't attach");
+ goto bad;
+ }
+
+ deva->d_isdef = 1;
+ if (has_errobj(attrs, &errattr))
+ goto bad;
+ for (nv = attrs; nv != NULL; nv = nv->nv_next) {
+ a = nv->nv_ptr;
+ if (a == &errattr)
+ continue; /* already complained */
+ if (a->a_iattr)
+ error("`%s' is not a plain attribute", a->a_name);
+ }
+
+ /* Committed! Set up fields. */
+ deva->d_attrs = attrs;
+ deva->d_atlist = atlist;
+ deva->d_vectors = vectors;
+ deva->d_devbase = dev;
+
+ /*
+ * Turn the `at' list into interface attributes (map each
+ * nv_name to an attribute, or to NULL for root), and add
+ * this device to those attributes, so that children can
+ * be listed at this particular device if they are supported
+ * by that attribute.
+ */
+ for (nv = atlist; nv != NULL; nv = nv->nv_next) {
+ if (nv->nv_name == NULL)
+ nv->nv_ptr = a = NULL; /* at root */
+ else
+ nv->nv_ptr = a = getattr(nv->nv_name);
+ if (a == &errattr)
+ continue; /* already complained */
+
+ /*
+ * Make sure that an attachment spec doesn't
+ * already say how to attach to this attribute.
+ */
+ for (da = dev->d_ahead; da != NULL; da = da->d_bsame)
+ if (onlist(da->d_atlist, a))
+ error("attach at `%s' already done by `%s'",
+ a ? a->a_name : "root", da->d_name);
+
+ if (a == NULL)
+ continue; /* at root; don't add */
+ if (!a->a_iattr)
+ error("%s cannot be at plain attribute `%s'",
+ dev->d_name, a->a_name);
+ else
+ a->a_devs = addtoattr(a->a_devs, dev);
+ }
+
+ /* attach to parent */
+ *dev->d_app = deva;
+ dev->d_app = &deva->d_bsame;
+ return;
+bad:
+ nvfreel(atlist);
+ nvfreel(vectors);
+ nvfreel(attrs);
+}
+
+/*
+ * Look up a device attachment. Also makes sure it is a reasonable
+ * name, i.e., does not contain digits or special characters.
+ */
+struct deva *
+getdevattach(name)
+ const char *name;
+{
+ register u_char *p;
+ register struct deva *deva;
+
+ p = (u_char *)name;
+ if (!isalpha(*p))
+ goto badname;
+ while (*++p) {
+ if (!isalnum(*p) && *p != '_')
+ goto badname;
+ }
+ if (isdigit(*--p)) {
+badname:
+ error("bad device attachment name `%s'", name);
+ return (&errdeva);
+ }
+ deva = ht_lookup(devatab, name);
+ if (deva == NULL) {
+ deva = emalloc(sizeof *deva);
+ deva->d_name = name;
+ deva->d_next = NULL;
+ deva->d_bsame = NULL;
+ deva->d_isdef = 0;
+ deva->d_devbase = NULL;
+ deva->d_atlist = NULL;
+ deva->d_vectors = NULL;
+ deva->d_attrs = NULL;
+ deva->d_ihead = NULL;
+ deva->d_ipp = &deva->d_ihead;
+ *nextdeva = deva;
+ nextdeva = &deva->d_next;
+ if (ht_insert(devatab, name, deva))
+ panic("getdeva(%s)", name);
+ }
+ return (deva);
+}
+
+/*
* Look up an attribute.
*/
struct attr *
@@ -421,7 +534,7 @@ exclude(nv, name, what)
return (0);
}
-/*
+/*
* Map things like "ra0b" => makedev(major("ra"), 0*maxpartitions + 'b'-'a').
* Handle the case where the device number is given but there is no
* corresponding name, and map NULL to the default.
@@ -453,7 +566,7 @@ resolve(nvp, name, what, dflt, part)
min = (minor(dflt->nv_int) / maxpartitions) + part;
d = makedev(maj, min);
}
- *nvp = nv = newnv(NULL, NULL, NULL, d);
+ *nvp = nv = newnv(NULL, NULL, NULL, d, NULL);
}
if (nv->nv_int != NODEV) {
/*
@@ -607,10 +720,12 @@ newdevi(name, unit, d)
i->i_base = d;
i->i_next = NULL;
i->i_bsame = NULL;
+ i->i_asame = NULL;
i->i_alias = NULL;
i->i_at = NULL;
i->i_atattr = NULL;
i->i_atdev = NULL;
+ i->i_atdeva = NULL;
i->i_locs = NULL;
i->i_cfflags = 0;
i->i_lineno = currentline();
@@ -634,11 +749,14 @@ adddev(name, at, loclist, flags)
register struct devbase *ib; /* i->i_base */
register struct devbase *ab; /* not NULL => at another dev */
register struct nvlist *nv;
+ register struct deva *iba; /* devbase attachment used */
const char *cp;
int atunit;
char atbuf[NAMESIZE];
+ int hit;
ab = NULL;
+ iba = NULL;
if (at == NULL) {
/* "at root" */
if ((i = getdevi(name)) == NULL)
@@ -649,7 +767,13 @@ adddev(name, at, loclist, flags)
* bother?). Make sure this device can be at root.
*/
ib = i->i_base;
- if (!onlist(ib->d_atlist, NULL)) {
+ hit = 0;
+ for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame)
+ if (onlist(iba->d_atlist, NULL)) {
+ hit = 1;
+ break;
+ }
+ if (!hit) {
error("%s's cannot attach to the root", ib->d_name);
goto bad;
}
@@ -664,38 +788,78 @@ adddev(name, at, loclist, flags)
goto bad;
ib = i->i_base;
cp = intern(atbuf);
- if ((attr = ht_lookup(attrtab, cp)) == NULL) {
- /*
- * Have to work a bit harder to see whether we have
- * something like "tg0 at esp0" (where esp is merely
- * not an attribute) or "tg0 at nonesuch0" (where
- * nonesuch is not even a device).
- */
- if ((ab = ht_lookup(devbasetab, cp)) == NULL) {
- error("%s at %s: `%s' unknown",
- name, at, atbuf);
- goto bad;
- }
- /*
- * See if the named parent carries an attribute
- * that allows it to supervise device ib.
- */
- for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {
- attr = nv->nv_ptr;
- if (onlist(attr->a_devs, ib))
- goto ok;
- }
- attr = &errattr;/* now onlist below will fail */
- }
- if (!onlist(attr->a_devs, ib)) {
- error("%s's cannot attach to %s's", ib->d_name, atbuf);
+
+ /*
+ * Devices can attach to two types of things: Attributes,
+ * and other devices (which have the appropriate attributes
+ * to allow attachment).
+ *
+ * (1) If we're attached to an attribute, then we don't need
+ * look at the parent base device to see what attributes
+ * it has, and make sure that we can attach to them.
+ *
+ * (2) If we're attached to a real device (i.e. named in
+ * the config file), we want to remember that so that
+ * at cross-check time, if the device we're attached to
+ * is missing but other devices which also provide the
+ * attribute are present, we don't get a false "OK."
+ *
+ * (3) If the thing we're attached to is an attribute
+ * but is actually named in the config file, we still
+ * have to remember its devbase.
+ */
+
+ /* Figure out parent's devbase, to satisfy case (3). */
+ ab = ht_lookup(devbasetab, cp);
+
+ /* Find out if it's an attribute. */
+ attr = ht_lookup(attrtab, cp);
+
+ /* Make sure we're _really_ attached to the attr. Case (1). */
+ if (attr != NULL && onlist(attr->a_devs, ib))
+ goto findattachment;
+
+ /*
+ * Else a real device, and not just an attribute. Case (2).
+ *
+ * Have to work a bit harder to see whether we have
+ * something like "tg0 at esp0" (where esp is merely
+ * not an attribute) or "tg0 at nonesuch0" (where
+ * nonesuch is not even a device).
+ */
+ if (ab == NULL) {
+ error("%s at %s: `%s' unknown",
+ name, at, atbuf);
goto bad;
}
+
+ /*
+ * See if the named parent carries an attribute
+ * that allows it to supervise device ib.
+ */
+ for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {
+ attr = nv->nv_ptr;
+ if (onlist(attr->a_devs, ib))
+ goto findattachment;
+ }
+ error("%s's cannot attach to %s's", ib->d_name, atbuf);
+ goto bad;
+
+findattachment:
+ /* find out which attachment it uses */
+ hit = 0;
+ for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame)
+ if (onlist(iba->d_atlist, attr)) {
+ hit = 1;
+ break;
+ }
+ if (!hit)
+ panic("adddev: can't figure out attachment");
}
ok:
if ((i->i_locs = fixloc(name, attr, loclist)) == NULL)
goto bad;
- if (i->i_unit == STAR && ib->d_vectors != NULL) {
+ if (i->i_unit == STAR && iba->d_vectors != NULL) {
error("%s's cannot be *'d as they have preset vectors",
ib->d_name);
goto bad;
@@ -703,9 +867,14 @@ ok:
i->i_at = at;
i->i_atattr = attr;
i->i_atdev = ab;
+ i->i_atdeva = iba;
i->i_atunit = atunit;
i->i_cfflags = flags;
- selectbase(ib);
+
+ *iba->d_ipp = i;
+ iba->d_ipp = &i->i_asame;
+
+ selectbase(ib, iba);
/* all done, fall into ... */
bad:
nvfreel(loclist);
@@ -736,7 +905,7 @@ addpseudo(name, number)
i = newdevi(name, number - 1, d); /* foo 16 => "foo0..foo15" */
if (ht_insert(devitab, name, i))
panic("addpseudo(%s)", name);
- selectbase(d);
+ selectbase(d, NULL);
*nextpseudo = i;
nextpseudo = &i->i_next;
npseudo++;
@@ -863,8 +1032,9 @@ split(name, nlen, base, bsize, aunit)
* attributes for "optional foo".
*/
static void
-selectbase(d)
+selectbase(d, da)
register struct devbase *d;
+ register struct deva *da;
{
register struct attr *a;
register struct nvlist *nv;
@@ -874,6 +1044,14 @@ selectbase(d)
a = nv->nv_ptr;
(void)ht_insert(selecttab, a->a_name, (char *)a->a_name);
}
+ if (da != NULL) {
+ (void)ht_insert(selecttab, da->d_name, (char *)da->d_name);
+ for (nv = da->d_attrs; nv != NULL; nv = nv->nv_next) {
+ a = nv->nv_ptr;
+ (void)ht_insert(selecttab, a->a_name,
+ (char *)a->a_name);
+ }
+ }
}
/*
diff --git a/usr.sbin/config/sem.h b/usr.sbin/config/sem.h
index 131762f7a47..ede56255b01 100644
--- a/usr.sbin/config/sem.h
+++ b/usr.sbin/config/sem.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: sem.h,v 1.2 1996/03/25 15:55:14 niklas Exp $ */
-/* $NetBSD: sem.h,v 1.2 1996/03/03 17:28:39 thorpej Exp $ */
+/* $OpenBSD: sem.h,v 1.3 1996/04/21 23:40:27 deraadt Exp $ */
+/* $NetBSD: sem.h,v 1.4 1996/03/17 06:29:40 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -51,8 +51,11 @@ void setdefmaxusers __P((int, int, int));
void setmaxusers __P((int));
int defattr __P((const char *, struct nvlist *));
void defdev __P((struct devbase *, int, struct nvlist *,
+ struct nvlist *));
+void defdevattach __P((struct deva *, struct devbase *,
struct nvlist *, struct nvlist *, struct nvlist *));
struct devbase *getdevbase __P((const char *name));
+struct deva *getdevattach __P((const char *name));
struct attr *getattr __P((const char *name));
void setmajor __P((struct devbase *d, int n));
void addconf __P((struct config *));
diff --git a/usr.sbin/config/util.c b/usr.sbin/config/util.c
index ca6b2eddb22..c9db10cda80 100644
--- a/usr.sbin/config/util.c
+++ b/usr.sbin/config/util.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: util.c,v 1.2 1996/03/25 15:55:16 niklas Exp $ */
-/* $NetBSD: util.c,v 1.2 1996/03/03 17:28:41 thorpej Exp $ */
+/* $OpenBSD: util.c,v 1.3 1996/04/21 23:40:28 deraadt Exp $ */
+/* $NetBSD: util.c,v 1.4 1996/03/17 11:50:16 cgd Exp $ */
-/*
+/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -60,7 +60,7 @@
static void nomem __P((void));
static void vxerror __P((const char *, int, const char *, va_list));
-/*
+/*
* Malloc, with abort on error.
*/
void *
@@ -74,7 +74,7 @@ emalloc(size)
return (p);
}
-/*
+/*
* Realloc, with abort on error.
*/
void *
@@ -120,10 +120,11 @@ path(file)
static struct nvlist *nvhead;
struct nvlist *
-newnv(name, str, ptr, i)
+newnv(name, str, ptr, i, next)
const char *name, *str;
void *ptr;
int i;
+ struct nvlist *next;
{
register struct nvlist *nv;
@@ -131,7 +132,7 @@ newnv(name, str, ptr, i)
nv = emalloc(sizeof(*nv));
else
nvhead = nv->nv_next;
- nv->nv_next = NULL;
+ nv->nv_next = next;
nv->nv_name = name;
if (ptr == NULL)
nv->nv_str = str;