summaryrefslogtreecommitdiff
path: root/sbin/sysctl/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/sysctl/sysctl.c')
-rw-r--r--sbin/sysctl/sysctl.c135
1 files changed, 133 insertions, 2 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 9b7c3095ed9..0cf34004c74 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.95 2003/06/11 06:22:15 deraadt Exp $ */
+/* $OpenBSD: sysctl.c,v 1.96 2003/08/21 18:56:07 tedu Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -40,7 +40,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95";
#else
-static char *rcsid = "$OpenBSD: sysctl.c,v 1.95 2003/06/11 06:22:15 deraadt Exp $";
+static char *rcsid = "$OpenBSD: sysctl.c,v 1.96 2003/08/21 18:56:07 tedu Exp $";
#endif
#endif /* not lint */
@@ -206,6 +206,7 @@ int sysctl_seminfo(char *, char **, int *, int, int *);
int sysctl_shminfo(char *, char **, int *, int, int *);
int sysctl_watchdog(char *, char **, int *, int, int *);
int sysctl_sensors(char *, char **, int *, int, int *);
+int sysctl_emul(char *, char *, int);
#ifdef CPU_CHIPSET
int sysctl_chipset(char *, char **, int *, int, int *);
#endif
@@ -430,6 +431,9 @@ parse(char *string, int flags)
if (len < 0)
return;
break;
+ case KERN_EMUL:
+ sysctl_emul(string, newval, flags);
+ return;
}
break;
@@ -1964,6 +1968,133 @@ sysctl_sensors(char *string, char **bufpp, int mib[], int flags, int *typep)
return (3);
}
+char **emul_names;
+int emul_num;
+void emul_init(void);
+
+int
+sysctl_emul(char *string, char *newval, int flags)
+{
+ int mib[4], enabled, i, old, found = 0;
+ char *head, *target;
+ size_t len;
+
+ emul_init();
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_EMUL;
+ mib[3] = KERN_EMUL_ENABLED;
+ head = "kern.emul.";
+
+ if (aflag || strcmp(string, "kern.emul") == 0) {
+ if (strcmp(string, "kern.emul") == 0 && wflag) {
+ warnx("%s: specification is incomplete", string);
+ return (1);
+ }
+ if (nflag)
+ printf("%d\n", emul_num);
+ else
+ printf("%snemuls = %d\n", head, emul_num);
+ for (i = 0; i < emul_num; i++) {
+ mib[2] = i + 1;
+ len = sizeof(int);
+ if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) {
+ warn("%s", string);
+ continue;
+ }
+ if (nflag)
+ printf("%d\n", enabled);
+ else
+ printf("%s%s = %d\n", head, emul_names[i],
+ enabled);
+ }
+ return (0);
+ }
+ /* User specified a third level name */
+ target = strrchr(string, '.');
+ target++;
+ if (strcmp(string, "nemuls") == 0) {
+ if (newval) {
+ warnx("Operation not permitted");
+ return (1);
+ }
+ if (nflag)
+ printf("%d\n", emul_num);
+ else
+ printf("%snemuls = %d\n", head, emul_num);
+ return (0);
+ }
+ for (i = 0; i < emul_num; i++) {
+ if (strcmp(target, emul_names[i]))
+ continue;
+ found = 1;
+ mib[2] = i + 1;
+ len = sizeof(int);
+ if (newval) {
+ enabled = atoi(newval);
+ if (sysctl(mib, 4, &old, &len, &enabled, len) == -1) {
+ warn("%s", string);
+ continue;
+ }
+ if (nflag)
+ printf("%d\n", enabled);
+ else
+ printf("%s%s: %d -> %d\n", head, target, old,
+ enabled);
+ } else {
+ if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) {
+ warn("%s", string);
+ continue;
+ }
+ if (nflag)
+ printf("%d\n", enabled);
+ else
+ printf("%s%s = %d\n", head, target, enabled);
+ }
+ }
+ if (!found)
+ warnx("third level name %s in kern.emul is invalid",
+ string);
+ return (0);
+
+
+}
+
+void
+emul_init(void)
+{
+ static int done;
+ char string[16];
+ int mib[4], i;
+ size_t len;
+
+ if (done)
+ return;
+ done = 1;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_EMUL;
+ mib[2] = KERN_EMUL_NUM;
+ len = sizeof(int);
+ if (sysctl(mib, 3, &emul_num, &len, NULL, 0) == -1)
+ return;
+
+ emul_names = malloc(emul_num * sizeof(char *));
+ if (emul_names == NULL) {
+ warn("emul_init");
+ return;
+ }
+
+ for (i = 0; i < emul_num; i++) {
+ mib[2] = i + 1;
+ mib[3] = 0;
+ len = sizeof(string);
+ if (sysctl(mib, 4, string, &len, NULL, 0) == -1)
+ break;
+ emul_names[i] = strdup(string);
+ }
+}
+
/*
* Scan a list of names searching for a particular name.
*/