summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/config/Makefile24
-rw-r--r--usr.sbin/config/cmd.c256
-rw-r--r--usr.sbin/config/cmd.h77
-rw-r--r--usr.sbin/config/config.h4
-rw-r--r--usr.sbin/config/exec.c188
-rw-r--r--usr.sbin/config/exec.h41
-rw-r--r--usr.sbin/config/exec_aout.c148
-rw-r--r--usr.sbin/config/exec_ecoff.c159
-rw-r--r--usr.sbin/config/exec_elf.c173
-rw-r--r--usr.sbin/config/main.c49
-rw-r--r--usr.sbin/config/misc.c86
-rw-r--r--usr.sbin/config/misc.h44
-rw-r--r--usr.sbin/config/ukc.c224
-rw-r--r--usr.sbin/config/ukc.h136
-rw-r--r--usr.sbin/config/ukcutil.c1275
15 files changed, 2870 insertions, 14 deletions
diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile
index c6421b1db68..51dbd1b0164 100644
--- a/usr.sbin/config/Makefile
+++ b/usr.sbin/config/Makefile
@@ -1,15 +1,35 @@
-# $OpenBSD: Makefile,v 1.4 1997/09/21 11:43:31 deraadt Exp $
+# $OpenBSD: Makefile,v 1.5 1999/10/04 20:00:50 deraadt Exp $
PROG= config
BINDIR= /usr/sbin
SRCS= files.c gram.y hash.c main.c mkheaders.c mkioconf.c mkmakefile.c \
- mkswap.c pack.c scan.l sem.c util.c
+ mkswap.c pack.c scan.l sem.c util.c \
+ ukc.c misc.c ukcutil.c cmd.c exec.c
+.if (${MACHINE_ARCH} == "alpha")
+CFLAGS+=-DECOFF_SUPPORT
+SRCS+= exec_ecoff.c
+.elif (${MACHINE_ARCH} == "mips") || (${MACHINE_ARCH} == "powerpc") || \
+ (${MACHINE_ARCH} == "hppa")
+CFLAGS+=-DELF_SUPPORT
+SRCS+= exec_elf.c
+.else
+CFLAGS+=-DAOUT_SUPPORT
+SRCS+= exec_aout.c
+.endif
+.if (${MACHINE} == "pmax")
+CFLAGS+=-DAOUT_SUPPORT
+SRCS+= exec_aout.c
+.endif
+
CFLAGS+=-I${.CURDIR} -I.
# This program actually requires "flex" (not just any old lex).
# Also note that it does not use -ll
LEX=flex
+LDADD= -lkvm
+DPADD= ${LIBKVM}
+
CLEANFILES=gram.c scan.c y.tab.h
MAN= config.8
diff --git a/usr.sbin/config/cmd.c b/usr.sbin/config/cmd.c
new file mode 100644
index 00000000000..d822f71ea51
--- /dev/null
+++ b/usr.sbin/config/cmd.c
@@ -0,0 +1,256 @@
+/* $OpenBSD: cmd.c,v 1.1 1999/10/04 20:00:50 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: cmd.c,v 1.1 1999/10/04 20:00:50 deraadt Exp $";
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+#include <nlist.h>
+#include <sys/device.h>
+#include "misc.h"
+#define CMD_NOEXTERN
+#include "cmd.h"
+#include "ukc.h"
+
+/* Our command table */
+cmd_table_t cmd_table[] = {
+ {"help", Xhelp, "\t\t", "Command help list"},
+ {"add", Xadd, "dev\t\t", "Add a device"},
+ {"base", Xbase, "8|10|16\t\t", "Base on large numbers"},
+ {"change", Xchange, "devno|dev\t", "Change device"},
+ {"disable",Xdisable, "attr val|devno|dev", "Disable device"},
+ {"enable", Xenable, "attr val|devno|dev", "Enable device"},
+ {"find", Xfind, "devno|dev\t", "Find device"},
+ {"list", Xlist, "\t\t", "List configuration"},
+ {"lines", Xlines, "count\t\t", "# of lines per page"},
+ {"show", Xshow, "[attr [val]]\t", "Show attribute"},
+ {"exit", Xexit, "\t\t", "Exit, without saving changes"},
+ {"quit", Xquit, "\t\t", "Quit, saving current changes"},
+ {NULL, NULL, NULL, NULL}
+};
+
+int
+Xhelp(cmd)
+ cmd_t *cmd;
+{
+ cmd_table_t *cmd_table = cmd->table;
+ int i;
+
+ /* Hmm, print out cmd_table here... */
+ for (i = 0; cmd_table[i].cmd != NULL; i++)
+ printf("\t%s\t%s\t%s\n", cmd_table[i].cmd,
+ cmd_table[i].opt, cmd_table[i].help);
+ return (CMD_CONT);
+}
+
+int
+Xadd(cmd)
+ cmd_t *cmd;
+{
+ int a;
+ short unit, state;
+
+ if (strlen(cmd->args) == 0)
+ printf("Dev expected\n");
+ else if (device(cmd->args, &a, &unit, &state) == 0)
+ add(cmd->args, a, unit, state);
+ else
+ printf("Unknown argument\n");
+ return (CMD_CONT);
+}
+
+int
+Xbase(cmd)
+ cmd_t *cmd;
+{
+ int a;
+
+ if (strlen(cmd->args) == 0)
+ printf("8|10|16 expected\n");
+ else if (number(&cmd->args[0], &a) == 0) {
+ if (a == 8 || a == 10 || a == 16) {
+ base = a;
+ } else {
+ printf("8|10|16 expected\n");
+ }
+ } else
+ printf("Unknown argument\n");
+
+ return (CMD_CONT);
+}
+
+int
+Xchange(cmd)
+ cmd_t *cmd;
+{
+ int a;
+ short unit, state;
+
+ if (strlen(cmd->args) == 0)
+ printf("DevNo or Dev expected\n");
+ else if (number(cmd->args, &a) == 0)
+ change(a);
+ else if (device(cmd->args, &a, &unit, &state) == 0)
+ common_dev(cmd->args, a, unit, state, UC_CHANGE);
+ else
+ printf("Unknown argument\n");
+
+ return (CMD_CONT);
+}
+
+int
+Xdisable(cmd)
+ cmd_t *cmd;
+{
+ int a;
+ short unit, state;
+
+ if (strlen(cmd->args) == 0)
+ printf("Attr, DevNo or Dev expected\n");
+ else if (attr(cmd->args, &a) == 0)
+ common_attr(cmd->args, a, UC_DISABLE);
+ else if (number(cmd->args, &a) == 0)
+ disable(a);
+ else if (device(cmd->args, &a, &unit, &state) == 0)
+ common_dev(cmd->args, a, unit, state, UC_DISABLE);
+ else
+ printf("Unknown argument\n");
+
+ return (CMD_CONT);
+}
+
+int
+Xenable(cmd)
+ cmd_t *cmd;
+{
+ int a;
+ short unit, state;
+
+ if (strlen(cmd->args) == 0)
+ printf("Attr, DevNo or Dev expected\n");
+ else if (attr(cmd->args, &a) == 0)
+ common_attr(cmd->args, a, UC_DISABLE);
+ else if (number(cmd->args, &a) == 0)
+ enable(a);
+ else if (device(cmd->args, &a, &unit, &state) == 0)
+ common_dev(cmd->args, a, unit, state, UC_ENABLE);
+ else
+ printf("Unknown argument\n");
+
+ return (CMD_CONT);
+}
+
+int
+Xfind(cmd)
+ cmd_t *cmd;
+{
+ int a;
+ short unit, state;
+
+ if (strlen(cmd->args) == 0)
+ printf("DevNo or Dev expected\n");
+ else if (number(cmd->args, &a) == 0)
+ pdev(a);
+ else if (device(cmd->args, &a, &unit, &state) == 0)
+ common_dev(cmd->args, a, unit, state, UC_FIND);
+ else
+ printf("Unknown argument\n");
+
+ return (CMD_CONT);
+}
+
+int
+Xlines(cmd)
+ cmd_t *cmd;
+{
+ int a;
+
+ if (strlen(cmd->args) == 0)
+ printf("Argument expected\n");
+ else if (number(cmd->args, &a) == 0)
+ lines = a;
+ else
+ printf("Unknown argument\n");
+ return (CMD_CONT);
+}
+
+int
+Xlist(cmd)
+ cmd_t *cmd;
+{
+ int i = 0;
+ struct cfdata *cd;
+
+ cnt = 0;
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ if (more())
+ break;
+ pdev(i++);
+ cd++;
+ }
+
+ cnt = -1;
+
+ return (CMD_CONT);
+}
+
+int
+Xshow(cmd)
+ cmd_t *cmd;
+{
+ if (strlen(cmd->args) == 0)
+ show();
+ else
+ show_attr(&cmd->args[0]);
+
+ return (CMD_CONT);
+}
+
+int
+Xquit(cmd)
+ cmd_t *cmd;
+{
+ /* Nothing to do here */
+ return (CMD_SAVE);
+}
+
+int
+Xexit(cmd)
+ cmd_t *cmd;
+{
+ /* Nothing to do here */
+ return (CMD_EXIT);
+}
diff --git a/usr.sbin/config/cmd.h b/usr.sbin/config/cmd.h
new file mode 100644
index 00000000000..b6c972a5a87
--- /dev/null
+++ b/usr.sbin/config/cmd.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: cmd.h,v 1.1 1999/10/04 20:00:50 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CMD_H
+#define _CMD_H
+
+/* Constants (returned by cmd funs) */
+#define CMD_EXIT 0x0000
+#define CMD_SAVE 0x0001
+#define CMD_CONT 0x0002
+
+/* Data types */
+struct _cmd_table_t;
+typedef struct _cmd_t {
+ struct _cmd_table_t *table;
+ char cmd[10];
+ char args[100];
+} cmd_t;
+
+typedef struct _cmd_table_t {
+ char *cmd;
+ int (*fcn)(cmd_t *);
+ char *opt;
+ char *help;
+} cmd_table_t;
+
+
+#ifndef CMD_NOEXTERN
+extern cmd_table_t cmd_table[];
+#endif
+
+/* Prototypes */
+int Xhelp __P((cmd_t *));
+int Xadd __P((cmd_t *));
+int Xbase __P((cmd_t *));
+int Xchange __P((cmd_t *));
+int Xdisable __P((cmd_t *));
+int Xenable __P((cmd_t *));
+int Xfind __P((cmd_t *));
+int Xlines __P((cmd_t *));
+int Xlist __P((cmd_t *));
+int Xshow __P((cmd_t *));
+int Xexit __P((cmd_t *));
+int Xquit __P((cmd_t *));
+
+#endif _CMD_H
+
+
diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h
index 30e989ef97d..6544d6822ea 100644
--- a/usr.sbin/config/config.h
+++ b/usr.sbin/config/config.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.h,v 1.12 1997/11/13 08:21:53 deraadt Exp $ */
+/* $OpenBSD: config.h,v 1.13 1999/10/04 20:00:50 deraadt Exp $ */
/* $NetBSD: config.h,v 1.30 1997/02/02 21:12:30 thorpej Exp $ */
/*
@@ -386,3 +386,5 @@ struct nvlist *newnv __P((const char *, const char *, void *, int,
struct nvlist *));
void nvfree __P((struct nvlist *));
void nvfreel __P((struct nvlist *));
+
+int ukc __P((char *, char *, int, int));
diff --git a/usr.sbin/config/exec.c b/usr.sbin/config/exec.c
new file mode 100644
index 00000000000..cebe4df885c
--- /dev/null
+++ b/usr.sbin/config/exec.c
@@ -0,0 +1,188 @@
+/* $OpenBSD: exec.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: exec.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#ifdef AOUT_SUPPORT
+int aout_check __P((char *));
+void aout_loadkernel __P((char *));
+void aout_savekernel __P((char *));
+caddr_t aout_adjust __P((caddr_t));
+caddr_t aout_readjust __P((caddr_t));
+#endif
+
+#ifdef ECOFF_SUPPORT
+int ecoff_check __P((char *));
+void ecoff_loadkernel __P((char *));
+void ecoff_savekernel __P((char *));
+caddr_t ecoff_adjust __P((caddr_t));
+caddr_t ecoff_readjust __P((caddr_t));
+#endif
+
+#ifdef ELF_SUPPORT
+int elf_check __P((char *));
+void elf_loadkernel __P((char *));
+void elf_savekernel __P((char *));
+caddr_t elf_adjust __P((caddr_t));
+caddr_t elf_readjust __P((caddr_t));
+#endif
+
+#define DO_AOUT 0
+#define DO_ECOFF 1
+#define DO_ELF 2
+
+int current_exec = -1;
+
+caddr_t
+adjust(x)
+ caddr_t x;
+{
+ switch (current_exec) {
+#ifdef AOUT_SUPPORT
+ case DO_AOUT:
+ return(aout_adjust(x));
+ break;
+#endif
+#ifdef ECOFF_SUPPORT
+ case DO_ECOFF:
+ return(ecoff_adjust(x));
+ break;
+#endif
+#ifdef ELF_SUPPORT
+ case DO_ELF:
+ return(elf_adjust(x));
+ break;
+#endif
+ default:
+ errx(1, "no supported exec type");
+ }
+}
+
+caddr_t
+readjust(x)
+ caddr_t x;
+{
+ switch (current_exec) {
+#ifdef AOUT_SUPPORT
+ case DO_AOUT:
+ return(aout_readjust(x));
+ break;
+#endif
+#ifdef ECOFF_SUPPORT
+ case DO_ECOFF:
+ return(ecoff_readjust(x));
+ break;
+#endif
+#ifdef ELF_SUPPORT
+ case DO_ELF:
+ return(elf_readjust(x));
+ break;
+#endif
+ default:
+ errx(1, "no supported exec type");
+ }
+}
+
+void
+loadkernel(file)
+ char *file;
+{
+ current_exec = -1;
+
+#ifdef AOUT_SUPPORT
+ if (aout_check(file)) {
+ current_exec = DO_AOUT;
+ }
+#endif
+
+#ifdef ECOFF_SUPPORT
+ if (ecoff_check(file)) {
+ current_exec = DO_ECOFF;
+ }
+#endif
+
+#ifdef ELF_SUPPORT
+ if (elf_check(file)) {
+ current_exec = DO_ELF;
+ }
+#endif
+
+ switch (current_exec) {
+#ifdef AOUT_SUPPORT
+ case DO_AOUT:
+ aout_loadkernel(file);
+ break;
+#endif
+#ifdef ECOFF_SUPPORT
+ case DO_ECOFF:
+ ecoff_loadkernel(file);
+ break;
+#endif
+#ifdef ELF_SUPPORT
+ case DO_ELF:
+ elf_loadkernel(file);
+ break;
+#endif
+ default:
+ errx(1, "no supported exec type");
+ }
+}
+
+void
+savekernel(outfile)
+ char *outfile;
+{
+ switch (current_exec) {
+#ifdef AOUT_SUPPORT
+ case DO_AOUT:
+ aout_savekernel(outfile);
+ break;
+#endif
+#ifdef ECOFF_SUPPORT
+ case DO_ECOFF:
+ ecoff_savekernel(outfile);
+ break;
+#endif
+#ifdef ELF_SUPPORT
+ case DO_ELF:
+ elf_savekernel(outfile);
+ break;
+#endif
+ default:
+ errx(1, "no supported exec type");
+ }
+}
diff --git a/usr.sbin/config/exec.h b/usr.sbin/config/exec.h
new file mode 100644
index 00000000000..b57afcf85cf
--- /dev/null
+++ b/usr.sbin/config/exec.h
@@ -0,0 +1,41 @@
+/* $OpenBSD: exec.h,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _EXEC_H
+#define _EXEC_H
+
+void loadkernel __P((char *));
+void savekernel __P((char *));
+caddr_t adjust __P((caddr_t));
+caddr_t readjust __P((caddr_t));
+
+#endif _EXEC_H
+
diff --git a/usr.sbin/config/exec_aout.c b/usr.sbin/config/exec_aout.c
new file mode 100644
index 00000000000..0647a77baef
--- /dev/null
+++ b/usr.sbin/config/exec_aout.c
@@ -0,0 +1,148 @@
+/* $OpenBSD: exec_aout.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: exec_aout.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/exec.h>
+#include <sys/types.h>
+
+#include "ukc.h"
+
+caddr_t aout_p,aout_r;
+int aout_psz = 0, aout_rsz = 0;
+struct exec aout_ex;
+
+caddr_t
+aout_adjust(x)
+ caddr_t x;
+{
+ unsigned long y;
+
+ y = (unsigned long)x - nl[P_KERNEL_TEXT].n_value + (unsigned long)aout_p +
+ N_TXTOFF(aout_ex);
+ return((caddr_t)y);
+}
+
+caddr_t
+aout_readjust(x)
+ caddr_t x;
+{
+ unsigned long y;
+
+ y = (unsigned long)x - (unsigned long)aout_p + nl[P_KERNEL_TEXT].n_value -
+ N_TXTOFF(aout_ex);
+ return((caddr_t)y);
+}
+
+int
+aout_check(file)
+ char *file;
+{
+ int fd, ret = 1;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ return (0);
+ if (read(fd, (char *)&aout_ex, sizeof(aout_ex)) != sizeof(aout_ex))
+ ret = 0;
+ if (ret) {
+ if (N_BADMAG(aout_ex))
+ ret = 0;
+ }
+
+ close(fd);
+ return (ret);
+}
+
+void
+aout_loadkernel(file)
+ char *file;
+{
+ int fd;
+ off_t cur,end;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ err(1, file, errno);
+
+ if (read(fd, (char *)&aout_ex, sizeof(aout_ex)) != sizeof(aout_ex))
+ errx(1, "can't read a.out header");
+
+ if (N_BADMAG(aout_ex))
+ errx(1, "bad a.out magic\n");
+
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+
+ aout_psz = (int)(aout_ex.a_text+aout_ex.a_data);
+
+ aout_p = malloc(aout_psz);
+
+ if (read(fd, aout_p, aout_psz) != aout_psz)
+ errx(1, "can't read a.out text and data");
+
+ cur = lseek(fd, (off_t)0, SEEK_CUR);
+ end = lseek(fd, (off_t)0, SEEK_END);
+ (void)lseek(fd, cur, SEEK_SET);
+
+ aout_rsz = (int)(end - cur);
+
+ aout_r = malloc(aout_rsz);
+
+ if (read(fd, aout_r, aout_rsz) != aout_rsz)
+ errx(1, "can't read rest of file %s", file);
+
+ close(fd);
+}
+
+void
+aout_savekernel(outfile)
+ char *outfile;
+{
+ int fd;
+
+ if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0)
+ err(1, outfile, errno);
+
+ if (write(fd, aout_p, aout_psz) != aout_psz)
+ errx(1, "can't write a.out text and data");
+
+ if (write(fd, aout_r, aout_rsz) != aout_rsz)
+ errx(1, "can't write rest of file %s", outfile);
+
+ close(fd);
+}
diff --git a/usr.sbin/config/exec_ecoff.c b/usr.sbin/config/exec_ecoff.c
new file mode 100644
index 00000000000..638eba23205
--- /dev/null
+++ b/usr.sbin/config/exec_ecoff.c
@@ -0,0 +1,159 @@
+/* $OpenBSD: exec_ecoff.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: exec_ecoff.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/exec.h>
+#include <sys/exec_ecoff.h>
+#include <sys/types.h>
+
+#include "ukc.h"
+
+caddr_t ecoff_p,ecoff_r,ecoff_b;
+int ecoff_psz = 0, ecoff_rsz = 0, ecoff_bsz = 0;
+struct ecoff_exechdr ecoff_ex;
+
+caddr_t
+ecoff_adjust(x)
+ caddr_t x;
+{
+ unsigned long y;
+
+ y = (unsigned long)x - nl[P_KERNEL_TEXT].n_value + (unsigned long)ecoff_p;
+
+ return((caddr_t)y);
+}
+
+caddr_t
+ecoff_readjust(x)
+ caddr_t x;
+{
+ unsigned long y;
+
+ y = (unsigned long)x - (unsigned long)ecoff_p + nl[P_KERNEL_TEXT].n_value;
+
+ return((caddr_t)y);
+}
+
+int
+ecoff_check(file)
+ char *file;
+{
+ int fd,ret = 1;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ return (0);
+
+ if (read(fd,(char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex))
+ ret = 0;
+
+ if (ret)
+ if (ECOFF_BADMAG(&ecoff_ex))
+ ret = 0;
+ }
+
+ close(fd);
+ return (ret);
+}
+
+void
+ecoff_loadkernel(file)
+ char *file;
+{
+ int fd;
+ off_t beg,cur,end;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ err(1, file, errno);
+
+ if (read(fd, (char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex))
+ errx(1, "can't read ecoff header");
+
+ if (ECOFF_BADMAG(&ecoff_ex))
+ errx(1, "bad ecoff magic\n");
+
+ ecoff_psz = ecoff_ex.a.tsize + ecoff_ex.a.dsize;
+ beg = lseek(fd, ECOFF_TXTOFF(&ecoff_ex), SEEK_SET);
+
+ ecoff_bsz = (int)beg;
+ ecoff_b = malloc(ecoff_bsz);
+
+ ecoff_p = malloc(ecoff_psz);
+
+ if (read(fd, ecoff_p, ecoff_psz) != ecoff_psz)
+ errx(1, "can't read ecoff text and data");
+
+ cur = lseek(fd, (off_t)0, SEEK_CUR);
+ end = lseek(fd, (off_t)0, SEEK_END);
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+ if (read(fd, ecoff_b, ecoff_bsz) != ecoff_bsz)
+ errx(1, "can't read begining of file %s", file);
+ (void)lseek(fd, cur, SEEK_SET);
+
+ ecoff_rsz = (int)(end - cur);
+
+ ecoff_r = malloc(ecoff_rsz);
+
+ if (read(fd, ecoff_r, ecoff_rsz) != ecoff_rsz)
+ errx(1, "can't read rest of file %s", file);
+
+ close(fd);
+}
+
+void
+ecoff_savekernel(outfile)
+ char *outfile;
+{
+ int fd;
+
+ if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0)
+ err(1, outfile, errno);
+
+ if (write(fd, ecoff_b, ecoff_bsz) != ecoff_bsz)
+ errx(1, "can't write beginning of file %s",outfile);
+
+ if (write(fd, ecoff_p, ecoff_psz) != ecoff_psz)
+ errx(1, "can't write ecoff text and data");
+
+ if (write(fd, ecoff_r, ecoff_rsz) != ecoff_rsz)
+ errx(1, "can't write rest of file %s", outfile);
+
+ close(fd);
+}
diff --git a/usr.sbin/config/exec_elf.c b/usr.sbin/config/exec_elf.c
new file mode 100644
index 00000000000..1446fa27012
--- /dev/null
+++ b/usr.sbin/config/exec_elf.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: exec_elf.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: exec_elf.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/exec.h>
+#include <sys/exec_elf.h>
+#include <sys/types.h>
+
+#include "ukc.h"
+
+caddr_t ptr,rest,pre;
+Elf32_Ehdr elf_ex;
+Elf32_Phdr *elf_phdr;
+Elf32_Shdr *elf_shdr;
+char *elf_total;
+char *elf_shstrtab;
+off_t elf_size;
+
+caddr_t
+elf_adjust(x)
+ caddr_t x;
+{
+ int i;
+ Elf32_Shdr *s;
+ unsigned long y = 0;
+
+ s = elf_shdr;
+
+ for (i = 0; i < elf_ex.e_shnum; i++) {
+ if (s[i].sh_addr == 0)
+ continue;
+ if (((unsigned long)x >= s[i].sh_addr) &&
+ ((unsigned long)x < (s[i].sh_addr+s[i].sh_size))) {
+ y = (unsigned long)&elf_total[(unsigned long)x -
+ s[i].sh_addr +
+ s[i].sh_offset];
+ break;
+ }
+ }
+
+ return((caddr_t)y);
+}
+
+caddr_t
+elf_readjust(x)
+ caddr_t x;
+{
+ int i;
+ Elf32_Shdr *s;
+ unsigned long y = 0;
+
+ s = elf_shdr;
+
+ for (i = 0; i < elf_ex.e_shnum; i++) {
+ if (s[i].sh_addr == 0)
+ continue;
+ if (((x - elf_total) >= s[i].sh_offset) &&
+ ((x - elf_total) <= (s[i].sh_offset + s[i].sh_size)))
+ y = x - elf_total + s[i].sh_addr;
+ }
+
+ return((caddr_t)y);
+}
+
+int
+elf_check(file)
+ char *file;
+{
+ int fd,ret = 1;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ return (0);
+
+ if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex))
+ ret = 0;
+
+ if (ret) {
+ if (!IS_ELF(elf_ex))
+ ret = 0;
+ }
+
+ close(fd);
+ return (ret);
+}
+
+void
+elf_loadkernel(file)
+ char *file;
+{
+ int fd;
+ Elf32_Phdr *p;
+ Elf32_Shdr *s;
+
+ if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
+ err(1, file, errno);
+
+ if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex))
+ errx(1, "can't read elf header");
+
+ if (!IS_ELF(elf_ex))
+ errx(1, "bad elf magic\n");
+
+ elf_size = lseek(fd, 0L, SEEK_END);
+ (void)lseek(fd, 0L, SEEK_SET);
+ elf_total = malloc(elf_size);
+
+ if (read(fd, elf_total, elf_size) != elf_size)
+ errx(1, "can't read elf kernel");
+
+ elf_phdr = (Elf32_Phdr *)&elf_total[elf_ex.e_phoff];
+ elf_shdr = (Elf32_Shdr *)&elf_total[elf_ex.e_shoff];
+
+ p = elf_phdr;
+ s = elf_shdr;
+
+ elf_shstrtab = &elf_total[elf_shdr[elf_ex.e_shstrndx].sh_offset];
+
+ close(fd);
+}
+
+void
+elf_savekernel(outfile)
+
+ char *outfile;
+{
+ int fd;
+
+ if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0)
+ err(1, outfile, errno);
+
+ if (write(fd, elf_total, elf_size) != elf_size)
+ errx(1, "can't write file %s", outfile);
+
+ close(fd);
+}
diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
index 9923d459187..70e7dd7a781 100644
--- a/usr.sbin/config/main.c
+++ b/usr.sbin/config/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.17 1998/05/25 09:35:06 deraadt Exp $ */
+/* $OpenBSD: main.c,v 1.18 1999/10/04 20:00:51 deraadt Exp $ */
/* $NetBSD: main.c,v 1.22 1997/02/02 21:12:33 thorpej Exp $ */
/*
@@ -85,6 +85,17 @@ static void optiondelta __P((void));
int madedir = 0;
+void
+usage()
+{
+ extern char *__progname;
+
+ fprintf(stderr, "usage: %s [-p] [-s srcdir] [-b builddir] sysname\n",
+ __progname);
+ fprintf(stderr, " %s -e [-u] [-o newkernel] kernel\n", __progname);
+ exit(1);
+}
+
int
main(argc, argv)
int argc;
@@ -92,12 +103,27 @@ main(argc, argv)
{
register char *p;
const char *last_component;
- int pflag, ch;
+ char *outfile = NULL;
+ int pflag, ch, eflag, uflag, fflag;
- pflag = 0;
- while ((ch = getopt(argc, argv, "gpb:s:")) != -1) {
+ pflag = eflag = uflag = fflag = 0;
+ while ((ch = getopt(argc, argv, "egpfb:s:o:u")) != -1) {
switch (ch) {
+ case 'o':
+ outfile = optarg;
+ break;
+ case 'u':
+ uflag = 1;
+ break;
+ case 'f':
+ fflag = 1;
+ break;
+
+ case 'e':
+ eflag = 1;
+ break;
+
case 'g':
/*
* In addition to DEBUG, you probably wanted to
@@ -108,7 +134,7 @@ main(argc, argv)
(void)fputs(
"-g is obsolete (use makeoptions DEBUG=\"-g\")\n",
stderr);
- goto usage;
+ usage();
case 'p':
/*
@@ -134,17 +160,18 @@ main(argc, argv)
case '?':
default:
- goto usage;
+ usage();
}
}
argc -= optind;
argv += optind;
- if (argc > 1) {
-usage:
- (void)fputs("usage: config [-p] [-s srcdir] [-b builddir] sysname\n", stderr);
- exit(1);
- }
+ if (argc > 1 || !argv[0])
+ usage();
+
+ if (eflag)
+ return (ukc(argv[0], outfile, uflag, fflag));
+
conffile = (argc == 1) ? argv[0] : "CONFIG";
if (firstfile(conffile)) {
(void)fprintf(stderr, "config: cannot read %s: %s\n",
diff --git a/usr.sbin/config/misc.c b/usr.sbin/config/misc.c
new file mode 100644
index 00000000000..316a8fc04cd
--- /dev/null
+++ b/usr.sbin/config/misc.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: misc.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: misc.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <err.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "misc.h"
+
+int
+ask_cmd(cmd)
+ cmd_t *cmd;
+{
+ char lbuf[100], *cp, *buf;
+
+ /* Get input */
+ if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ errx(1, "eof");
+ lbuf[strlen(lbuf)-1] = '\0';
+
+ /* Parse input */
+ buf = lbuf;
+ buf = &buf[strspn(buf, " \t")];
+ cp = &buf[strcspn(buf, " \t")];
+ *cp++ = '\0';
+ strncpy(cmd->cmd, buf, 10);
+ buf = &cp[strspn(cp, " \t")];
+ strncpy(cmd->args, buf, 100);
+
+ return (0);
+}
+
+int
+ask_yn(str)
+ const char *str;
+{
+ int ch, first;
+
+ printf("%s [n] ", str);
+ fflush(stdout);
+
+ first = ch = getchar();
+ while (ch != '\n' && ch != EOF)
+ ch = getchar();
+
+ if (ch == EOF || first == EOF)
+ errx(1, "eof");
+
+ return (first == 'y' || first == 'Y');
+}
diff --git a/usr.sbin/config/misc.h b/usr.sbin/config/misc.h
new file mode 100644
index 00000000000..788b3620148
--- /dev/null
+++ b/usr.sbin/config/misc.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: misc.h,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1997 Tobias Weingartner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Tobias Weingartner.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MISC_H
+#define _MISC_H
+
+#include <sys/types.h>
+#include "cmd.h"
+
+/* Prototypes */
+int ask_cmd __P((cmd_t *));
+int ask_yn __P((const char *));
+
+#endif _MISC_H
+
diff --git a/usr.sbin/config/ukc.c b/usr.sbin/config/ukc.c
new file mode 100644
index 00000000000..6b4907e24fa
--- /dev/null
+++ b/usr.sbin/config/ukc.c
@@ -0,0 +1,224 @@
+/* $OpenBSD: ukc.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ukc.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+
+#include <err.h>
+#include <kvm.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define UKC_MAIN
+#include "ukc.h"
+#include "exec.h"
+
+void init __P((void));
+void usage __P((void));
+
+int
+ukc(file, outfile, uflag, force)
+ char *file;
+ char *outfile;
+ int uflag;
+ int force;
+{
+ extern char *__progname;
+ int ret, i;
+ kvm_t *kd;
+ char errbuf[_POSIX2_LINE_MAX];
+ int histlen = 0, ok = 1;
+ char history[1024], kversion[1024];
+
+ if (file == NULL) {
+ fprintf(stderr, "%s: no file specified\n", __progname);
+ usage();
+ }
+
+ loadkernel(file);
+
+ ret = nlist(file, nl);
+
+ if (uflag) {
+
+ if ((kd = kvm_openfiles(NULL,NULL,NULL,O_RDONLY, errbuf)) == 0)
+ errx(1, "kvm_openfiles: %s", errbuf);
+
+ if ((ret = kvm_nlist(kd, knl)) == -1)
+ errx(1, "kvm_nlist: %s", kvm_geterr(kd));
+
+ i = 0;
+ while (i < NLENTRIES) {
+ if ((nl[i].n_type != knl[i].n_type) ||
+ (nl[i].n_desc != knl[i].n_desc) ||
+ (nl[i].n_value != knl[i].n_value))
+ ok = 0;
+ i++;
+ }
+
+ if ((knl[I_HISTLEN].n_type != 0) && ok) {
+ if (kvm_read(kd, knl[I_HISTLEN].n_value, &histlen,
+ sizeof(histlen)) != sizeof(histlen))
+ warnx("cannot read %s: %s",
+ knl[I_HISTLEN].n_name,
+ kvm_geterr(kd));
+ }
+ if ((knl[CA_HISTORY].n_type != 0) && ok) {
+ if (kvm_read(kd, knl[CA_HISTORY].n_value, history,
+ sizeof(history)) != sizeof(history))
+ warnx("cannot read %s: %s",
+ knl[CA_HISTORY].n_name,
+ kvm_geterr(kd));
+ }
+ if ((knl[P_VERSION].n_type != 0) && ok) {
+ if (kvm_read(kd, knl[P_VERSION].n_value, kversion,
+ sizeof(kversion)) != sizeof(kversion))
+ warnx("cannot read %s: %s",
+ knl[P_VERSION].n_name,
+ kvm_geterr(kd));
+ }
+ }
+
+ printf("%s", adjust((caddr_t)nl[P_VERSION].n_value));
+
+ if (force == 0 && outfile == NULL)
+ printf("warning: not output file specified\n");
+
+ init();
+
+ if ((nl[IA_EXTRALOC].n_type == 0) ||
+ (nl[I_NEXTRALOC].n_type == 0) ||
+ (nl[I_UEXTRALOC].n_type == 0) ||
+ (nl[I_HISTLEN].n_type == 0) ||
+ (nl[CA_HISTORY].n_type == 0)) {
+ printf("\
+WARNING this kernel doesn't contain all information needed!\n\
+WARNING the commands add and change might not work.\n");
+ oldkernel = 1;
+ }
+
+ if (uflag) {
+ if (ok) {
+ if (strcmp(adjust((caddr_t)nl[P_VERSION].n_value),
+ kversion) != 0)
+ ok = 1;
+ }
+ if (!ok) {
+ printf("WARNING kernel mismatch. -u ignored.\n");
+ printf("WARNING the running kernel version:\n");
+ printf("%s",kversion);
+ } else {
+ process_history(histlen,history);
+ }
+ }
+
+ if (config()) {
+ if (force == 0 && outfile == NULL) {
+ fprintf(stderr, "not forced\n");
+ exit(1);
+ }
+ if (outfile == NULL)
+ outfile = file;
+ savekernel(outfile);
+ }
+
+ return(0);
+}
+
+void
+init()
+{
+ int i = 0,fd;
+ struct cfdata *cd;
+ short *ln;
+#ifdef NOTDEF
+ struct winsize w;
+#endif
+
+ cd = get_cfdata(0); /* get first item */
+
+ while(cd->cf_attach != 0) {
+ maxdev = i;
+ totdev = i;
+
+ ln = get_locnamp(cd->cf_locnames);
+ while (*ln != -1) {
+ if (*ln > maxlocnames)
+ maxlocnames = *ln;
+ ln++;
+ }
+ i++;
+ cd++;
+ }
+
+ while(cd->cf_attach == 0) {
+ totdev = i;
+ i++;
+ cd++;
+ }
+
+ totdev = totdev - 1;
+
+ if ((fd = open("/dev/tty", O_RDWR)) < 0)
+ fd = 2;
+
+#ifdef NOTDEF
+ if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
+ printf("row %d col %d\n",w.ws_row,w.ws_col);
+ }
+
+ if ((s = getenv("LINES")) != NULL)
+ sc_height = atoi(s);
+ else
+ sc_height = tgetnum("li");
+
+ if (sc_height <= 0)
+ sc_height = 24;
+
+ if ((s = getenv("COLUMNS")) != NULL)
+ sc_width = atoi(s);
+ else
+ sc_width = tgetnum("co");
+
+ if (sc_width <= 0)
+ sc_width = 80;
+#endif
+}
diff --git a/usr.sbin/config/ukc.h b/usr.sbin/config/ukc.h
new file mode 100644
index 00000000000..a042fddcd04
--- /dev/null
+++ b/usr.sbin/config/ukc.h
@@ -0,0 +1,136 @@
+/* $OpenBSD: ukc.h,v 1.1 1999/10/04 20:00:52 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UKC_H
+#define _UKC_H
+
+#define P_LOCNAMES 0
+#define S_LOCNAMP 1
+#define SA_CFROOTS 2
+#define I_CFROOTS_SIZE 3
+#define I_PV_SIZE 4
+#define SA_PV 5
+#define P_CFDATA 6
+#define P_KERNEL_TEXT 7
+#define P_VERSION 8
+#define IA_EXTRALOC 9
+#define I_NEXTRALOC 10
+#define I_UEXTRALOC 11
+#define I_HISTLEN 12
+#define CA_HISTORY 13
+#define NLENTRIES 14
+
+#ifdef UKC_MAIN
+struct nlist nl[] = {
+ { "_locnames" },
+ { "_locnamp" },
+ { "_cfroots" },
+ { "_cfroots_size" },
+ { "_pv_size" },
+ { "_pv" },
+ { "_cfdata" },
+ { "_kernel_text" },
+ { "_version" },
+ { "_extraloc" },
+ { "_nextraloc" },
+ { "_uextraloc" },
+ { "_userconf_histlen" },
+ { "_userconf_history" },
+};
+struct nlist knl[] = {
+ { "_locnames" },
+ { "_locnamp" },
+ { "_cfroots" },
+ { "_cfroots_size" },
+ { "_pv_size" },
+ { "_pv" },
+ { "_cfdata" },
+ { "_kernel_text" },
+ { "_version" },
+ { "_extraloc" },
+ { "_nextraloc" },
+ { "_uextraloc" },
+ { "_userconf_histlen" },
+ { "_userconf_history" },
+};
+int maxdev = 0;
+int totdev = 0;
+int maxlocnames = 0;
+int base = 16;
+int cnt = -1;
+int lines = 18;
+int oldkernel = 0;
+#else
+extern struct nlist nl[];
+extern int maxdev;
+extern int totdev;
+extern int maxlocnames;
+extern int base;
+extern int cnt;
+extern int lines;
+extern int oldkernel;
+#endif
+
+struct cfdata *get_cfdata __P((int));
+short *get_locnamp __P((int));
+caddr_t *get_locnames __P((int));
+int *get_extraloc __P((int));
+
+int more __P(());
+void pnum __P((int));
+void pdevnam __P((short));
+void pdev __P((short));
+int number __P((char *, int *));
+int device __P((char *, int *, short *, short *));
+int attr __P((char *, int *));
+void modify __P((char *, int *));
+void change __P((int));
+void disable __P((int));
+void enable __P((int));
+void show __P((void));
+void common_attr_val __P((short, int *, char));
+void show_attr __P((char *));
+void common_dev __P((char *, int, short, short, char));
+void common_attr __P((char *, int, char));
+void add_read __P((char *, char, char *, int, int *));
+void add __P((char *, int, short, short));
+
+int config __P(());
+void process_history __P((int, char *));
+
+#define UC_CHANGE 'c'
+#define UC_DISABLE 'd'
+#define UC_ENABLE 'e'
+#define UC_FIND 'f'
+#define UC_SHOW 's'
+
+#endif _UTIL_H
+
diff --git a/usr.sbin/config/ukcutil.c b/usr.sbin/config/ukcutil.c
new file mode 100644
index 00000000000..7c730194aab
--- /dev/null
+++ b/usr.sbin/config/ukcutil.c
@@ -0,0 +1,1275 @@
+/* $OpenBSD: ukcutil.c,v 1.1 1999/10/04 20:00:52 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Mats O Jansson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mats O Jansson.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LINT
+static char rcsid[] = "$OpenBSD: ukcutil.c,v 1.1 1999/10/04 20:00:52 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/device.h>
+#include <limits.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cmd.h"
+#include "exec.h"
+#include "ukc.h"
+#include "misc.h"
+
+struct cfdata *
+get_cfdata(idx)
+ int idx;
+{
+ return((struct cfdata *)(adjust((caddr_t)nl[P_CFDATA].n_value) +
+ idx*sizeof(struct cfdata)));
+}
+
+short *
+get_locnamp(idx)
+ int idx;
+{
+ return((short *)(adjust((caddr_t)nl[S_LOCNAMP].n_value) +
+ idx*sizeof(short)));
+}
+
+caddr_t *
+get_locnames(idx)
+ int idx;
+{
+ return((caddr_t *)(adjust((caddr_t)nl[P_LOCNAMES].n_value) +
+ idx*sizeof(caddr_t)));
+}
+
+int *
+get_extraloc(idx)
+ int idx;
+{
+ return((int *)(adjust((caddr_t)nl[IA_EXTRALOC].n_value) +
+ idx*sizeof(int)));
+}
+
+int
+more()
+{
+ int quit = 0;
+ cmd_t cmd;
+
+ if (cnt != -1) {
+ if (cnt == lines) {
+ printf("--- more ---");
+ fflush(stdout);
+ ask_cmd(&cmd);
+ cnt = 0;
+ }
+ cnt++;
+ if (cmd.cmd[0] == 'q' || cmd.cmd[0] == 'Q')
+ quit = 1;
+ }
+
+ return (quit);
+}
+
+void
+pnum(val)
+ int val;
+{
+ if (val > -2 && val < 16) {
+ printf("%d",val);
+ } else {
+ switch (base) {
+ case 8:
+ printf("0%o",val);
+ break;
+ case 10:
+ printf("%d",val);
+ break;
+ case 16:
+ default:
+ printf("0x%x",val);
+ break;
+ }
+ }
+}
+
+void
+pdevnam(devno)
+ short devno;
+{
+ struct cfdata *cd;
+ struct cfdriver *cdrv;
+
+ cd = get_cfdata(devno);
+
+ cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
+
+#if defined(OLDSCSIBUS)
+ if (strlen(adjust((caddr_t)cdrv->cd_name)) == 0) {
+ printf("oldscsibus");
+ }
+#endif
+ printf("%s", adjust((caddr_t)cdrv->cd_name));
+
+ switch (cd->cf_fstate) {
+ case FSTATE_NOTFOUND:
+ case FSTATE_DNOTFOUND:
+ printf("%d", cd->cf_unit);
+ break;
+ case FSTATE_FOUND:
+ printf("*FOUND*");
+ break;
+ case FSTATE_STAR:
+ case FSTATE_DSTAR:
+ printf("*");
+ break;
+ default:
+ printf("*UNKNOWN*");
+ break;
+ }
+}
+
+void
+pdev(devno)
+ short devno;
+{
+ struct cfdata *cd;
+ short *s,*ln;
+ int *i;
+ caddr_t *p;
+ char c;
+
+ if (devno > maxdev) {
+ printf("Unknown devno (max is %d)\n", maxdev);
+ return;
+ }
+
+ cd = get_cfdata(devno);
+
+ printf("%3d ", devno);
+ pdevnam(devno);
+ printf(" at");
+
+ c = ' ';
+ s = (short *)adjust((caddr_t)cd->cf_parents);
+ if (*s == -1)
+ printf(" root");
+ while (*s != -1) {
+ printf("%c", c);
+ pdevnam(*s);
+ c = '|';
+ s++;
+ }
+ switch (cd->cf_fstate) {
+ case FSTATE_NOTFOUND:
+ case FSTATE_FOUND:
+ case FSTATE_STAR:
+ break;
+ case FSTATE_DNOTFOUND:
+ case FSTATE_DSTAR:
+ printf(" disable");
+ break;
+ default:
+ printf(" ???");
+ break;
+ }
+
+ i = (int *)adjust((caddr_t)cd->cf_loc);
+ ln = get_locnamp(cd->cf_locnames);
+ while (*ln != -1) {
+ p = get_locnames(*ln);
+ printf(" %s ", adjust((caddr_t)*p));
+ ln++;
+ pnum(*i);
+ i++;
+ }
+ printf("\n");
+}
+
+int
+number(c, val)
+ char *c;
+ int *val;
+{
+ u_int num = 0;
+ int neg = 0;
+ int base = 10;
+
+ if (*c == '-') {
+ neg = 1;
+ c++;
+ }
+ if (*c == '0') {
+ base = 8;
+ c++;
+ if (*c == 'x' || *c == 'X') {
+ base = 16;
+ c++;
+ }
+ }
+ while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') {
+ u_char cc = *c;
+
+ if (cc >= '0' && cc <= '9')
+ cc = cc - '0';
+ else if (cc >= 'a' && cc <= 'f')
+ cc = cc - 'a' + 10;
+ else if (cc >= 'A' && cc <= 'F')
+ cc = cc - 'A' + 10;
+ else
+ return (-1);
+
+ if (cc > base)
+ return (-1);
+ num = num * base + cc;
+ c++;
+ }
+
+ if (neg && num > INT_MAX) /* overflow */
+ return (1);
+ *val = neg ? - num : num;
+ return (0);
+}
+
+int
+device(cmd, len, unit, state)
+ char *cmd;
+ int *len;
+ short *unit, *state;
+{
+ short u = 0, s = FSTATE_FOUND;
+ int l = 0;
+ char *c;
+
+ c = cmd;
+ while (*c >= 'a' && *c <= 'z') {
+ l++;
+ c++;
+ }
+ if (*c == '*') {
+ s = FSTATE_STAR;
+ c++;
+ } else {
+ while (*c >= '0' && *c <= '9') {
+ s = FSTATE_NOTFOUND;
+ u = u*10 + *c - '0';
+ c++;
+ }
+ }
+ while (*c == ' ' || *c == '\t' || *c == '\n')
+ c++;
+
+ if (*c == '\0') {
+ *len = l;
+ *unit = u;
+ *state = s;
+ return(0);
+ }
+
+ return(-1);
+}
+
+int
+attr(cmd, val)
+ char *cmd;
+ int *val;
+{
+ char *c;
+ caddr_t *p;
+ short attr = -1, i = 0, l = 0;
+
+ c = cmd;
+ while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
+ c++;
+ l++;
+ }
+
+ p = get_locnames(0);
+
+ while (i <= maxlocnames) {
+ if (strlen((char *)adjust((caddr_t)*p)) == l) {
+ if (strncasecmp(cmd, adjust((caddr_t)*p), l) == 0)
+ attr = i;
+ }
+ p++;
+ i++;
+ }
+
+ if (attr == -1) {
+ return (-1);
+ }
+
+ *val = attr;
+
+ return(0);
+}
+
+void
+modify(item, val)
+ char *item;
+ int *val;
+{
+ cmd_t cmd;
+ int a;
+
+ while(1) {
+ printf("%s [", item);
+ pnum(*val);
+ printf("] ? ");
+ fflush(stdout);
+
+ ask_cmd(&cmd);
+
+ if (strlen(cmd.cmd) != 0) {
+ if (strlen(cmd.args) == 0) {
+ if (number(cmd.cmd, &a) == 0) {
+ *val = a;
+ break;
+ } else
+ printf("Unknown argument\n");
+ } else
+ printf("Too many arguments\n");
+ } else {
+ break;
+ }
+ }
+}
+
+void
+change(devno)
+ int devno;
+{
+ struct cfdata *cd,*c;
+ caddr_t *p;
+ int i,share = 0,*j,*k,*l;
+ short *ln,*lk;
+
+ j = k = NULL;
+
+ if (devno <= maxdev) {
+
+ pdev(devno);
+
+ if (ask_yn("change")) {
+
+ cd = get_cfdata(devno);
+
+ /*
+ * Search for some other driver sharing this
+ * locator table. if one does, we may need to
+ * replace the locators with a new copy.
+ */
+
+ c = get_cfdata(0);
+ for (i = 0; c->cf_driver; i++) {
+ if (i != devno && c->cf_loc == cd->cf_loc)
+ share = 1;
+ c++;
+ }
+
+ ln = get_locnamp(cd->cf_locnames);
+ l = (int *)adjust((caddr_t)cd->cf_loc);
+
+ if (share) {
+ if (oldkernel) {
+ printf("Can't do that on this kernel\n");
+ return;
+ }
+
+ lk = ln;
+ i = 0;
+ while (*lk != -1) {
+ lk++; i++;
+ }
+ lk = ln;
+
+ j = (int *)adjust((caddr_t)nl[I_NEXTRALOC].n_value);
+ k = (int *)adjust((caddr_t)nl[I_UEXTRALOC].n_value);
+ if ((i + *k) > *j) {
+ printf("Not enough space to change device.\n");
+ return;
+ }
+
+ j = l = get_extraloc(*k);
+
+ bcopy(adjust((caddr_t)cd->cf_loc),
+ l, sizeof(int) * i);
+ }
+
+ while (*ln != -1) {
+ p = get_locnames(*ln);
+ modify((char *)adjust(*p),l);
+ ln++;
+ l++;
+ }
+
+ if (share) {
+ if (bcmp(adjust((caddr_t)cd->cf_loc),
+ j, sizeof(int) * i)) {
+ cd->cf_loc = (int *)readjust((caddr_t)j);
+ *k = *k + i;
+ }
+ }
+
+ printf("%3d ", devno);
+ pdevnam(devno);
+ printf(" changed\n");
+ pdev(devno);
+ }
+ } else {
+ printf("Unknown devno (max is %d)\n", maxdev);
+ }
+}
+
+void
+change_history(devno,str)
+ int devno;
+ char *str;
+{
+ struct cfdata *cd,*c;
+ caddr_t *p;
+ int i,share = 0,*j,*k,*l;
+ short *ln,*lk;
+
+ j = k = NULL;
+
+ if (devno <= maxdev) {
+
+ pdev(devno);
+
+ cd = get_cfdata(devno);
+
+ /*
+ * Search for some other driver sharing this
+ * locator table. if one does, we may need to
+ * replace the locators with a new copy.
+ */
+
+ c = get_cfdata(0);
+ for (i = 0; c->cf_driver; i++) {
+ if (i != devno && c->cf_loc == cd->cf_loc)
+ share = 1;
+ c++;
+ }
+
+ ln = get_locnamp(cd->cf_locnames);
+ l = (int *)adjust((caddr_t)cd->cf_loc);
+
+ if (share) {
+ if (oldkernel) {
+ printf("Can't do that on this kernel\n");
+ return;
+ }
+
+ lk = ln;
+ i = 0;
+ while (*lk != -1) {
+ lk++; i++;
+ }
+ lk = ln;
+
+ j = (int *)adjust((caddr_t)nl[I_NEXTRALOC].n_value);
+ k = (int *)adjust((caddr_t)nl[I_UEXTRALOC].n_value);
+ if ((i + *k) > *j) {
+ printf("Not enough space to change device.\n");
+ return;
+ }
+
+ j = l = get_extraloc(*k);
+
+ bcopy(adjust((caddr_t)cd->cf_loc),
+ l, sizeof(int) * i);
+ }
+
+ while (*ln != -1) {
+ p = get_locnames(*ln);
+ *l = atoi(str);
+ if (*str == '-') str++;
+ while ((*str >= '0') && (*str <= '9')) str++;
+ if (*str == ' ') str++;
+ ln++;
+ l++;
+ }
+
+ if (share) {
+ if (bcmp(adjust((caddr_t)cd->cf_loc),
+ j, sizeof(int) * i)) {
+ cd->cf_loc = (int *)readjust((caddr_t)j);
+ *k = *k + i;
+ }
+ }
+
+ printf("%3d ", devno);
+ pdevnam(devno);
+ printf(" changed\n");
+ pdev(devno);
+
+ } else {
+ printf("Unknown devno (max is %d)\n", maxdev);
+ }
+}
+
+void
+disable(devno)
+ int devno;
+{
+ struct cfdata *cd;
+ int done = 0;
+
+ if (devno <= maxdev) {
+
+ cd = get_cfdata(devno);
+
+ switch (cd->cf_fstate) {
+ case FSTATE_NOTFOUND:
+ cd->cf_fstate = FSTATE_DNOTFOUND;
+ break;
+ case FSTATE_STAR:
+ cd->cf_fstate = FSTATE_DSTAR;
+ break;
+ case FSTATE_DNOTFOUND:
+ case FSTATE_DSTAR:
+ done = 1;
+ break;
+ default:
+ printf("Error unknown state\n");
+ break;
+ }
+
+ printf("%3d ", devno);
+ pdevnam(devno);
+ if (done)
+ printf(" already");
+ printf(" disabled\n");
+ } else {
+ printf("Unknown devno (max is %d)\n", maxdev);
+ }
+}
+
+void
+enable(devno)
+ int devno;
+{
+ struct cfdata *cd;
+ int done = 0;
+
+ if (devno <= maxdev) {
+
+ cd = get_cfdata(devno);
+
+ switch (cd->cf_fstate) {
+ case FSTATE_DNOTFOUND:
+ cd->cf_fstate = FSTATE_NOTFOUND;
+ break;
+ case FSTATE_DSTAR:
+ cd->cf_fstate = FSTATE_STAR;
+ break;
+ case FSTATE_NOTFOUND:
+ case FSTATE_STAR:
+ done = 1;
+ break;
+ default:
+ printf("Error unknown state\n");
+ break;
+ }
+
+ printf("%3d ", devno);
+ pdevnam(devno);
+ if (done)
+ printf(" already");
+ printf(" enabled\n");
+ } else {
+ printf("Unknown devno (max is %d)\n", maxdev);
+ }
+}
+
+void
+show()
+{
+ caddr_t *p;
+ int i = 0;
+
+ cnt = 0;
+
+ p = get_locnames(0);
+
+ while (i <= maxlocnames) {
+ if (more())
+ break;
+ printf("%s\n", (char *)adjust(*p));
+ p++;
+ i++;
+ }
+
+ cnt = -1;
+}
+
+void
+common_attr_val(attr, val, routine)
+ short attr;
+ int *val;
+ char routine;
+{
+ int i = 0;
+ struct cfdata *cd;
+ int *l;
+ short *ln;
+ int quit = 0;
+
+ cnt = 0;
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ l = (int *)adjust((caddr_t)cd->cf_loc);
+ ln = get_locnamp(cd->cf_locnames);
+ while(*ln != -1) {
+ if (*ln == attr) {
+ if (val == NULL) {
+ quit = more();
+ pdev(i);
+ } else {
+ if (*val == *l) {
+ quit = more();
+ switch (routine) {
+ case UC_ENABLE:
+ enable(i);
+ break;
+ case UC_DISABLE:
+ disable(i);
+ break;
+ case UC_SHOW:
+ pdev(i);
+ break;
+ default:
+ printf("Unknown routine /%c/\n",
+ routine);
+ break;
+ }
+ }
+ }
+ }
+ if (quit)
+ break;
+ ln++;
+ l++;
+ }
+ if (quit)
+ break;
+ i++;
+ cd++;
+ }
+
+ cnt = -1;
+}
+
+void
+show_attr(cmd)
+ char *cmd;
+{
+ char *c;
+ caddr_t *p;
+ short attr = -1, i = 0, l = 0;
+ int a;
+
+ c = cmd;
+ while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
+ c++;
+ l++;
+ }
+ while (*c == ' ' || *c == '\t' || *c == '\n') {
+ c++;
+ }
+
+ p = get_locnames(0);
+
+ while (i <= maxlocnames) {
+ if (strlen((char *)adjust(*p)) == l) {
+ if (strncasecmp(cmd, adjust(*p), l) == 0) {
+ attr = i;
+ }
+ }
+ p++;
+ i++;
+ }
+
+ if (attr == -1) {
+ printf("Unknown attribute\n");
+ return;
+ }
+
+ if (*c == '\0') {
+ common_attr_val(attr, NULL, UC_SHOW);
+ } else {
+ if (number(c, &a) == 0) {
+ common_attr_val(attr, &a, UC_SHOW);
+ } else {
+ printf("Unknown argument\n");
+ }
+ }
+}
+
+void
+common_dev(dev, len, unit, state, routine)
+ char *dev;
+ int len;
+ short unit, state;
+ char routine;
+{
+ struct cfdata *cd;
+ struct cfdriver *cdrv;
+ int i = 0;
+
+ switch (routine) {
+ case UC_CHANGE:
+ break;
+ default:
+ cnt = 0;
+ break;
+ }
+
+ cnt = 0;
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len) {
+ /*
+ * Ok, if device name is correct
+ * If state == FSTATE_FOUND, look for "dev"
+ * If state == FSTATE_STAR, look for "dev*"
+ * If state == FSTATE_NOTFOUND, look for "dev0"
+ */
+ if (strncasecmp(dev,(char *)adjust(cdrv->cd_name),
+ len) == 0 &&
+ (state == FSTATE_FOUND ||
+ (state == FSTATE_STAR &&
+ (cd->cf_fstate == FSTATE_STAR ||
+ cd->cf_fstate == FSTATE_DSTAR)) ||
+ (state == FSTATE_NOTFOUND &&
+ cd->cf_unit == unit &&
+ (cd->cf_fstate == FSTATE_NOTFOUND ||
+ cd->cf_fstate == FSTATE_DNOTFOUND)))) {
+ if (more())
+ break;
+ switch (routine) {
+ case UC_CHANGE:
+ change(i);
+ break;
+ case UC_ENABLE:
+ enable(i);
+ break;
+ case UC_DISABLE:
+ disable(i);
+ break;
+ case UC_FIND:
+ pdev(i);
+ break;
+ default:
+ printf("Unknown routine /%c/\n",
+ routine);
+ break;
+ }
+ }
+ }
+ i++;
+ cd++;
+ }
+
+ switch (routine) {
+ case UC_CHANGE:
+ break;
+ default:
+ cnt = -1;
+ break;
+ }
+}
+
+void
+common_attr(cmd, attr, routine)
+ char *cmd;
+ int attr;
+ char routine;
+{
+ char *c;
+ short l = 0;
+ int a;
+
+ c = cmd;
+ while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
+ c++;
+ l++;
+ }
+ while (*c == ' ' || *c == '\t' || *c == '\n') {
+ c++;
+ }
+ if (*c == '\0') {
+ printf("Value missing for attribute\n");
+ return;
+ }
+
+ if (number(c, &a) == 0) {
+ common_attr_val(attr, &a, routine);
+ } else {
+ printf("Unknown argument\n");
+ }
+}
+
+void
+add_read(prompt, field, dev, len, val)
+ char *prompt;
+ char field;
+ char *dev;
+ int len;
+ int *val;
+{
+ int ok = 0;
+ int a;
+ cmd_t cmd;
+ struct cfdata *cd;
+ struct cfdriver *cdrv;
+
+ while(!ok) {
+ printf("%s ? ", prompt);
+ fflush(stdout);
+
+ ask_cmd(&cmd);
+
+ if (strlen(cmd.cmd) != 0) {
+ if (number(cmd.cmd, &a) == 0) {
+ if (a > maxdev) {
+ printf("Unknown devno (max is %d)\n",
+ maxdev);
+ } else {
+ cd = get_cfdata(a);
+ cdrv = (struct cfdriver *)
+ adjust((caddr_t)cd->cf_driver);
+ if (strncasecmp(dev,
+ (char *)adjust(cdrv->cd_name),
+ len) != 0 &&
+ field == 'a') {
+ printf("Not same device type\n");
+ } else {
+ *val = a;
+ ok = 1;
+ }
+ }
+ } else if (cmd.cmd[0] == '?') {
+ common_dev(dev, len, 0,
+ FSTATE_FOUND, UC_FIND);
+ } else if (cmd.cmd[0] == 'q' ||
+ cmd.cmd[0] == 'Q') {
+ ok = 1;
+ } else {
+ printf("Unknown argument\n");
+ }
+ } else {
+ ok = 1;
+ }
+ }
+
+}
+
+void
+add(dev, len, unit, state)
+ char *dev;
+ int len;
+ short unit, state;
+{
+ int i = 0, found = 0, *p;
+ short *pv;
+ struct cfdata new,*cd,*cdp;
+ struct cfdriver *cdrv;
+ int val, max_unit;
+
+ bzero(&new, sizeof(struct cfdata));
+
+ if (maxdev == totdev) {
+ printf("No more space for new devices.\n");
+ return;
+ }
+
+ if (state == FSTATE_FOUND) {
+ printf("Device not complete number or * is missing/n");
+ return;
+ }
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len &&
+ strncasecmp(dev, (char *)adjust(cdrv->cd_name), len) == 0)
+ found = 1;
+ cd++;
+ }
+
+ if (!found) {
+ printf("No device of this type exists.\n");
+ return;
+ }
+
+ add_read("Clone Device (DevNo, 'q' or '?')", 'a', dev, len, &val);
+
+ if (val != -1) {
+ cd = get_cfdata(val);
+ new = *cd;
+ new.cf_unit = unit;
+ new.cf_fstate = state;
+ add_read("Insert before Device (DevNo, 'q' or '?')",
+ 'i', dev, len, &val);
+ }
+
+ if (val != -1) {
+
+ /* Insert the new record */
+ cdp = cd = get_cfdata(maxdev+1);
+ cdp--;
+ for (i = maxdev; val <= i; i--) {
+ *cd-- = *cdp--;
+ }
+ cd = get_cfdata(val);
+ *cd = new;
+
+ /* Fix indexs in pv */
+ p = (int *)adjust((caddr_t)nl[I_PV_SIZE].n_value);
+ pv = (short *)adjust((caddr_t)nl[SA_PV].n_value);
+ for (i = 0; i < *p; i++) {
+ if ((*pv != 1) && (*pv >= val))
+ *pv = *pv + 1;
+ pv++;
+ }
+
+ /* Fix indexs in cfroots */
+ p = (int *)adjust((caddr_t)nl[I_CFROOTS_SIZE].n_value);
+ pv = (short *)adjust((caddr_t)nl[SA_CFROOTS].n_value);
+ for (i = 0; i < *p; i++) {
+ if ((*pv != 1) && (*pv >= val))
+ *pv = *pv + 1;
+ pv++;
+ }
+
+ maxdev++;
+
+ max_unit = -1;
+
+ /* Find max unit number of the device type */
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)
+ adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len &&
+ strncasecmp(dev, (char *)adjust(cdrv->cd_name),
+ len) == 0) {
+ switch (cd->cf_fstate) {
+ case FSTATE_NOTFOUND:
+ case FSTATE_DNOTFOUND:
+ if (cd->cf_unit > max_unit)
+ max_unit = cd->cf_unit;
+ break;
+ default:
+ break;
+ }
+ }
+ cd++;
+ }
+
+
+ /* For all * entries set unit number to max+1 */
+
+ max_unit++;
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)
+ adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len &&
+ strncasecmp(dev, (char *)adjust(cdrv->cd_name),
+ len) == 0) {
+ switch (cd->cf_fstate) {
+ case FSTATE_STAR:
+ case FSTATE_DSTAR:
+ cd->cf_unit = max_unit;
+ break;
+ default:
+ break;
+ }
+ }
+ cd++;
+ }
+
+ pdev(val);
+ }
+
+ /* cf_attach, cf_driver, cf_unit, cf_state, cf_loc, cf_flags,
+ cf_parents, cf_locnames, cf_locnames and cf_ivstubs */
+}
+
+void
+add_history(devno, unit, state, newno)
+ int devno, newno;
+ short unit, state;
+{
+ int i = 0, *p;
+ short *pv;
+ struct cfdata new,*cd,*cdp;
+ struct cfdriver *cdrv;
+ int val, max_unit;
+ int len;
+ char *dev;
+
+ bzero(&new, sizeof(struct cfdata));
+
+ cd = get_cfdata(devno);
+ new = *cd;
+ new.cf_unit = unit;
+ new.cf_fstate = state;
+
+ val = newno;
+
+ cdrv = (struct cfdriver *) adjust((caddr_t)cd->cf_driver);
+ dev = adjust((caddr_t)cdrv->cd_name);
+ len = strlen(dev);
+
+ /* Insert the new record */
+ cdp = cd = get_cfdata(maxdev+1);
+ cdp--;
+ for (i = maxdev; val <= i; i--) {
+ *cd-- = *cdp--;
+ }
+ cd = get_cfdata(val);
+ *cd = new;
+
+ /* Fix indexs in pv */
+ p = (int *)adjust((caddr_t)nl[I_PV_SIZE].n_value);
+ pv = (short *)adjust((caddr_t)nl[SA_PV].n_value);
+ for (i = 0; i < *p; i++) {
+ if ((*pv != 1) && (*pv >= val))
+ *pv = *pv + 1;
+ pv++;
+ }
+
+ /* Fix indexs in cfroots */
+ p = (int *)adjust((caddr_t)nl[I_CFROOTS_SIZE].n_value);
+ pv = (short *)adjust((caddr_t)nl[SA_CFROOTS].n_value);
+ for (i = 0; i < *p; i++) {
+ if ((*pv != 1) && (*pv >= val))
+ *pv = *pv + 1;
+ pv++;
+ }
+
+ maxdev++;
+
+ max_unit = -1;
+
+ /* Find max unit number of the device type */
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)
+ adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len &&
+ strncasecmp(dev, (char *)adjust(cdrv->cd_name),
+ len) == 0) {
+ switch (cd->cf_fstate) {
+ case FSTATE_NOTFOUND:
+ case FSTATE_DNOTFOUND:
+ if (cd->cf_unit > max_unit)
+ max_unit = cd->cf_unit;
+ break;
+ default:
+ break;
+ }
+ }
+ cd++;
+ }
+
+
+ /* For all * entries set unit number to max+1 */
+
+ max_unit++;
+
+ cd = get_cfdata(0);
+
+ while(cd->cf_attach != 0) {
+ cdrv = (struct cfdriver *)
+ adjust((caddr_t)cd->cf_driver);
+
+ if (strlen((char *)adjust(cdrv->cd_name)) == len &&
+ strncasecmp(dev, (char *)adjust(cdrv->cd_name),
+ len) == 0) {
+ switch (cd->cf_fstate) {
+ case FSTATE_STAR:
+ case FSTATE_DSTAR:
+ cd->cf_unit = max_unit;
+ break;
+ default:
+ break;
+ }
+ }
+ cd++;
+ }
+
+
+ printf("%3d ", newno);
+ pdevnam(newno);
+ printf(" added\n");
+ pdev(val);
+
+}
+
+int
+config()
+{
+ cmd_t cmd;
+ int i, st;
+
+ /* Set up command table pointer */
+ cmd.table = cmd_table;
+
+ printf("Enter 'help' for information\n");
+
+ /* Edit cycle */
+ do {
+again:
+ printf("ukc> ");
+ fflush(stdout);
+ ask_cmd(&cmd);
+
+ if (cmd.cmd[0] == '\0')
+ goto again;
+ for (i = 0; cmd_table[i].cmd != NULL; i++)
+ if (strstr(cmd_table[i].cmd, cmd.cmd)==cmd_table[i].cmd)
+ break;
+
+ /* Quick hack to put in '?' == 'help' */
+ if (!strcmp(cmd.cmd, "?"))
+ i = 0;
+
+ /* Check for valid command */
+ if (cmd_table[i].cmd == NULL) {
+ printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);
+ continue;
+ } else
+ strcpy(cmd.cmd, cmd_table[i].cmd);
+
+ /* Call function */
+ st = cmd_table[i].fcn(&cmd);
+
+ /* Update status */
+ if (st == CMD_EXIT)
+ break;
+ if (st == CMD_SAVE)
+ break;
+ } while (1);
+
+ return (st == CMD_SAVE);
+}
+
+void
+process_history(len,buf)
+ int len;
+ char *buf;
+{
+ char *c;
+ int devno,newno;
+ short unit,state;
+
+ if (len == 0) {
+ printf("History is empty\n");
+ return;
+ }
+
+ printf("Processing history...\n");
+
+ buf[len] = 0;
+
+ c = buf;
+
+ while (*c != NULL) {
+ switch (*c) {
+ case 'a':
+ c++; c++;
+ devno = atoi(c);
+ while ((*c >= '0') && (*c <= '9')) c++; c++;
+ unit = atoi(c);
+ if (*c == '-') c++;
+ while ((*c >= '0') && (*c <= '9')) c++; c++;
+ state = atoi(c);
+ if (*c == '-') c++;
+ while ((*c >= '0') && (*c <= '9')) c++; c++;
+ newno = atoi(c);
+ while ((*c >= '0') && (*c <= '9')) c++;
+ add_history(devno,unit,state,newno);
+ while (*c != '\n') c++; c++;
+ break;
+ case 'c':
+ c++; c++;
+ devno = atoi(c);
+ while ((*c >= '0') && (*c <= '9')) c++;
+ if (*c == ' ') c++;
+ if (*c != '\n') {
+ change_history(devno,c);
+ }
+ while (*c != '\n') c++; c++;
+ break;
+ case 'd':
+ c++;
+ devno = atoi(c);
+ disable(devno);
+ while (*c != '\n') c++; c++;
+ break;
+ case 'e':
+ c++;
+ devno = atoi(c);
+ enable(devno);
+ while (*c != '\n') c++; c++;
+ break;
+ case 'q':
+ while (*c != NULL) c++;
+ break;
+ default:
+ printf("unknown command %c\n",*c);
+ while ((*c != NULL) && (*c != '\n')) c++;
+ break;
+ }
+ }
+}