diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-10-04 20:00:53 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-10-04 20:00:53 +0000 |
commit | 2269932dd4c3a3c5ae5e59158c7d17a19fce7f5f (patch) | |
tree | 0edcb3bb5778adef2a6fa1552e2714ffe14d0f6d /usr.sbin/config | |
parent | f9fe2fe5ac0f4b50d179b5b57a9b7e245bcb4f78 (diff) |
config -e support; ukc from maja@
Diffstat (limited to 'usr.sbin/config')
-rw-r--r-- | usr.sbin/config/Makefile | 24 | ||||
-rw-r--r-- | usr.sbin/config/cmd.c | 256 | ||||
-rw-r--r-- | usr.sbin/config/cmd.h | 77 | ||||
-rw-r--r-- | usr.sbin/config/config.h | 4 | ||||
-rw-r--r-- | usr.sbin/config/exec.c | 188 | ||||
-rw-r--r-- | usr.sbin/config/exec.h | 41 | ||||
-rw-r--r-- | usr.sbin/config/exec_aout.c | 148 | ||||
-rw-r--r-- | usr.sbin/config/exec_ecoff.c | 159 | ||||
-rw-r--r-- | usr.sbin/config/exec_elf.c | 173 | ||||
-rw-r--r-- | usr.sbin/config/main.c | 49 | ||||
-rw-r--r-- | usr.sbin/config/misc.c | 86 | ||||
-rw-r--r-- | usr.sbin/config/misc.h | 44 | ||||
-rw-r--r-- | usr.sbin/config/ukc.c | 224 | ||||
-rw-r--r-- | usr.sbin/config/ukc.h | 136 | ||||
-rw-r--r-- | usr.sbin/config/ukcutil.c | 1275 |
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; + } + } +} |