Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Implement sysctl descriptions. Now all that remains is actu...
details: https://anonhg.NetBSD.org/src/rev/909e06b5aa9e
branches: trunk
changeset: 559843:909e06b5aa9e
user: atatat <atatat%NetBSD.org@localhost>
date: Wed Mar 24 18:11:09 2004 +0000
description:
Implement sysctl descriptions. Now all that remains is actually to
write them.
diffstat:
sbin/sysctl/sysctl.c | 208 ++++++++++++++++++++++++++++++++++++++-
sys/kern/kern_sysctl.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 450 insertions(+), 14 deletions(-)
diffs (truncated from 639 to 300 lines):
diff -r 213d53377b24 -r 909e06b5aa9e sbin/sysctl/sysctl.c
--- a/sbin/sysctl/sysctl.c Wed Mar 24 17:44:22 2004 +0000
+++ b/sbin/sysctl/sysctl.c Wed Mar 24 18:11:09 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysctl.c,v 1.83 2004/03/24 15:34:56 atatat Exp $ */
+/* $NetBSD: sysctl.c,v 1.84 2004/03/24 18:11:09 atatat Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
#if 0
static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: sysctl.c,v 1.83 2004/03/24 15:34:56 atatat Exp $");
+__RCSID("$NetBSD: sysctl.c,v 1.84 2004/03/24 18:11:09 atatat Exp $");
#endif
#endif /* not lint */
@@ -140,6 +140,9 @@
static void parse(char *);
static void parse_create(char *);
static void parse_destroy(char *);
+static void parse_describe(char *);
+static void getdesc1(int *, u_int, struct sysctlnode *);
+static void getdesc(int *, u_int, struct sysctlnode *);
static void sysctlerror(int);
/*
@@ -234,7 +237,7 @@
#endif /* defined(lint) */
};
-int Aflag, aflag, Mflag, nflag, qflag, rflag, wflag, xflag;
+int Aflag, aflag, dflag, Mflag, nflag, qflag, rflag, wflag, xflag;
int req;
FILE *warnfp = stderr;
@@ -259,7 +262,7 @@
int name[CTL_MAXNAME];
int ch;
- while ((ch = getopt(argc, argv, "Aabef:Mnqrwx")) != -1) {
+ while ((ch = getopt(argc, argv, "Aabdef:Mnqrwx")) != -1) {
switch (ch) {
case 'A':
Aflag++;
@@ -267,6 +270,9 @@
case 'a':
aflag++;
break;
+ case 'd':
+ dflag++;
+ break;
case 'e':
eq = "=";
break;
@@ -309,7 +315,7 @@
usage(); */
/* if (aflag && Mflag)
usage(); */
- if ((Aflag || Mflag) && argc == 0 && fn == NULL)
+ if ((Aflag || Mflag || dflag) && argc == 0 && fn == NULL)
aflag = 1;
if (Aflag)
@@ -540,6 +546,29 @@
}
}
+ if (dflag && pnode != &my_root) {
+ if (Aflag || type != CTLTYPE_NODE) {
+ if (pnode->sysctl_desc == NULL)
+ getdesc1(name, namelen, pnode);
+ if (Aflag ||
+ (pnode->sysctl_desc != NULL &&
+ pnode->sysctl_desc != (const char*)-1)) {
+ if (!nflag)
+ printf("%s: ", gsname);
+ if (pnode->sysctl_desc == NULL ||
+ pnode->sysctl_desc == (const char*)-1)
+ printf("(no description)\n");
+ else
+ printf("%s\n", pnode->sysctl_desc);
+ }
+ }
+
+ if (type != CTLTYPE_NODE) {
+ *sp = *dp = '\0';
+ return;
+ }
+ }
+
/*
* if this is an alias and we added our name, that means we
* got here by recursing down into the tree, so skip it. The
@@ -584,10 +613,16 @@
if (p != NULL)
(*p->ps_p)(gsname, gdname, NULL, name, namelen,
pnode, type, p->ps_d);
- else if ((Aflag || req) && !Mflag)
+ else if ((Aflag || req) && !Mflag && !dflag)
printf("%s: no children\n", gsname);
}
else {
+ if (dflag)
+ /*
+ * get all descriptions for next level
+ * in one chunk
+ */
+ getdesc(name, namelen, pnode);
req = 0;
for (ni = 0; ni < pnode->sysctl_clen; ni++) {
name[namelen] = node[ni].sysctl_num;
@@ -683,7 +718,7 @@
{
struct sysctlnode *node;
struct handlespec *w;
- int name[CTL_MAXNAME];
+ int name[CTL_MAXNAME], dodesc = 0;
u_int namelen, type;
char *key, *value, *dot;
size_t sz;
@@ -709,6 +744,17 @@
else if (strncmp(key + 2, "destroy", 7) == 0 &&
(key[9] == '=' || key[9] == sep[0]))
parse_destroy(key + 9 + (key[9] == '='));
+ else if (strncmp(key + 2, "describe", 8) == 0 &&
+ (key[10] == '=' || key[10] == sep[0])) {
+ key += 10 + (key[10] == '=');
+ if ((value = strchr(key, '=')) != NULL)
+ parse_describe(key);
+ else {
+ if (!dflag)
+ dodesc = 1;
+ break;
+ }
+ }
else
fprintf(warnfp, "%s: unable to parse '%s'\n",
getprogname(), key);
@@ -729,7 +775,11 @@
type = SYSCTL_TYPE(node->sysctl_flags);
if (value == NULL) {
+ if (dodesc)
+ dflag = 1;
print_tree(&name[0], namelen, node, type, 0);
+ if (dodesc)
+ dflag = 0;
gsname[0] = '\0';
return;
}
@@ -1291,6 +1341,55 @@
st(SYSCTL_TYPE(node.sysctl_flags)));
}
+static void
+parse_describe(char *l)
+{
+ struct sysctlnode newdesc;
+ char buf[1024], *value;
+ struct sysctldesc *d = (void*)&buf[0];
+ int name[CTL_MAXNAME], rc;
+ u_int namelen;
+ size_t sz;
+
+ if (!wflag) {
+ fprintf(warnfp,
+ "%s: Must specify -w to set descriptions\n",
+ getprogname());
+ exit(1);
+ }
+
+ value = strchr(l, '=');
+ *value++ = '\0';
+
+ memset(name, 0, sizeof(name));
+ namelen = sizeof(name) / sizeof(name[0]);
+ sz = sizeof(gsname);
+ rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL,
+ SYSCTL_VERSION);
+ if (rc == -1) {
+ fprintf(warnfp,
+ "%s: %s level name '%s' in '%s' is invalid\n",
+ getprogname(), lname[namelen], gsname, l);
+ exit(1);
+ }
+
+ sz = sizeof(buf);
+ memset(&newdesc, 0, sizeof(newdesc));
+ newdesc.sysctl_flags = SYSCTL_VERSION|CTLFLAG_OWNDESC;
+ newdesc.sysctl_num = name[namelen - 1];
+ newdesc.sysctl_desc = value;
+ name[namelen - 1] = CTL_DESCRIBE;
+ rc = sysctl(name, namelen, d, &sz, &newdesc, sizeof(newdesc));
+ if (rc == -1)
+ fprintf(warnfp, "%s: %s: CTL_DESCRIBE failed: %s\n",
+ getprogname(), gsname, strerror(errno));
+ else if (d->descr_len == 1)
+ fprintf(warnfp, "%s: %s: description not set\n",
+ getprogname(), gsname);
+ else if (!qflag && !nflag)
+ printf("%s: %s\n", gsname, d->descr_str);
+}
+
/*
* ********************************************************************
* when things go wrong...
@@ -1317,6 +1416,101 @@
exit(1);
}
+static void
+getdesc1(int *name, u_int namelen, struct sysctlnode *pnode)
+{
+ struct sysctlnode node;
+ char buf[1024], *desc;
+ struct sysctldesc *d = (void*)buf;
+ size_t sz = sizeof(buf);
+ int rc;
+
+ memset(&node, 0, sizeof(node));
+ node.sysctl_flags = SYSCTL_VERSION;
+ node.sysctl_num = name[namelen - 1];
+ name[namelen - 1] = CTL_DESCRIBE;
+ rc = sysctl(name, namelen, d, &sz, &node, sizeof(node));
+
+ if (rc == -1 ||
+ d->descr_len == 1 ||
+ d->descr_num != pnode->sysctl_num ||
+ d->descr_ver != pnode->sysctl_ver)
+ desc = (char *)-1;
+ else
+ desc = malloc(d->descr_len);
+
+ if (desc == NULL)
+ desc = (char *)-1;
+ if (desc != (char *)-1)
+ memcpy(desc, &d->descr_str[0], sz);
+ name[namelen - 1] = node.sysctl_num;
+ if (pnode->sysctl_desc != NULL &&
+ pnode->sysctl_desc != (const char *)-1)
+ free((void*)pnode->sysctl_desc);
+ pnode->sysctl_desc = desc;
+}
+
+static void
+getdesc(int *name, u_int namelen, struct sysctlnode *pnode)
+{
+ struct sysctlnode *node = pnode->sysctl_child;
+ struct sysctldesc *d, *p;
+ char *desc;
+ size_t sz;
+ int rc, i;
+
+ sz = 128 * pnode->sysctl_clen;
+ name[namelen] = CTL_DESCRIBE;
+
+ /*
+ * attempt *twice* to get the description chunk. if two tries
+ * doesn't work, give up.
+ */
+ i = 0;
+ do {
+ d = malloc(128 * pnode->sysctl_clen);
+ if (d == NULL)
+ return;
+ rc = sysctl(name, namelen + 1, d, &sz, NULL, 0);
+ if (rc == -1) {
+ free(d);
+ d = NULL;
+ if (i == 0 && errno == ENOMEM)
+ i = 1;
+ else
+ return;
+ }
+ } while (d == NULL);
+
+ /*
+ * hokey nested loop here, giving O(n**2) behavior, but should
+ * suffice for now
+ */
+ for (i = 0; i < pnode->sysctl_clen; i++) {
+ node = &pnode->sysctl_child[i];
+ for (p = d; (char *)p < (char *)d + sz; p = NEXT_DESCR(p))
+ if (node->sysctl_num == p->descr_num)
+ break;
+ if ((char *)p < (char *)d + sz &&
+ node[i].sysctl_ver == p->descr_ver) {
+ /*
+ * match found, attempt to attach description
+ */
+ if (p->descr_len == 1)
+ desc = NULL;
+ else
+ desc = malloc(p->descr_len);
+ if (desc == NULL)
+ desc = (char *)-1;
+ else
+ memcpy(desc, &p->descr_str[0], sz);
Home |
Main Index |
Thread Index |
Old Index