| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: sysctl.c,v 1.157 2015/12/13 14:24:47 christos Exp $ */ | | 1 | /* $NetBSD: sysctl.c,v 1.158 2016/07/31 23:30:28 dholland Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Andrew Brown. | | 8 | * by Andrew Brown. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | * SUCH DAMAGE. | | 58 | * SUCH DAMAGE. |
59 | */ | | 59 | */ |
60 | | | 60 | |
61 | #include <sys/cdefs.h> | | 61 | #include <sys/cdefs.h> |
62 | #ifndef lint | | 62 | #ifndef lint |
63 | __COPYRIGHT("@(#) Copyright (c) 1993\ | | 63 | __COPYRIGHT("@(#) Copyright (c) 1993\ |
64 | The Regents of the University of California. All rights reserved."); | | 64 | The Regents of the University of California. All rights reserved."); |
65 | #endif /* not lint */ | | 65 | #endif /* not lint */ |
66 | | | 66 | |
67 | #ifndef lint | | 67 | #ifndef lint |
68 | #if 0 | | 68 | #if 0 |
69 | static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93"; | | 69 | static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93"; |
70 | #else | | 70 | #else |
71 | __RCSID("$NetBSD: sysctl.c,v 1.157 2015/12/13 14:24:47 christos Exp $"); | | 71 | __RCSID("$NetBSD: sysctl.c,v 1.158 2016/07/31 23:30:28 dholland Exp $"); |
72 | #endif | | 72 | #endif |
73 | #endif /* not lint */ | | 73 | #endif /* not lint */ |
74 | | | 74 | |
75 | #include <sys/types.h> | | 75 | #include <sys/types.h> |
76 | #include <sys/param.h> | | 76 | #include <sys/param.h> |
77 | #include <sys/sysctl.h> | | 77 | #include <sys/sysctl.h> |
78 | #include <sys/mount.h> | | 78 | #include <sys/mount.h> |
79 | #include <sys/resource.h> | | 79 | #include <sys/resource.h> |
80 | #include <sys/stat.h> | | 80 | #include <sys/stat.h> |
81 | #include <sys/sched.h> | | 81 | #include <sys/sched.h> |
82 | #include <sys/socket.h> | | 82 | #include <sys/socket.h> |
83 | #include <sys/bitops.h> | | 83 | #include <sys/bitops.h> |
84 | #include <netinet/in.h> | | 84 | #include <netinet/in.h> |
| @@ -118,28 +118,28 @@ __RCSID("$NetBSD: sysctl.c,v 1.157 2015/ | | | @@ -118,28 +118,28 @@ __RCSID("$NetBSD: sysctl.c,v 1.157 2015/ |
118 | u_int type, void *v | | 118 | u_int type, void *v |
119 | #define DISPLAY_VALUE 0 | | 119 | #define DISPLAY_VALUE 0 |
120 | #define DISPLAY_OLD 1 | | 120 | #define DISPLAY_OLD 1 |
121 | #define DISPLAY_NEW 2 | | 121 | #define DISPLAY_NEW 2 |
122 | | | 122 | |
123 | /* | | 123 | /* |
124 | * generic routines | | 124 | * generic routines |
125 | */ | | 125 | */ |
126 | static const struct handlespec *findhandler(const char *, regex_t *, size_t *); | | 126 | static const struct handlespec *findhandler(const char *, regex_t *, size_t *); |
127 | static void canonicalize(const char *, char *); | | 127 | static void canonicalize(const char *, char *); |
128 | static void purge_tree(struct sysctlnode *); | | 128 | static void purge_tree(struct sysctlnode *); |
129 | static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *, | | 129 | static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *, |
130 | size_t *); | | 130 | size_t *); |
131 | static void write_number(int *, u_int, struct sysctlnode *, char *); | | 131 | static void write_number(int *, u_int, struct sysctlnode *, char *, bool); |
132 | static void write_string(int *, u_int, struct sysctlnode *, char *); | | 132 | static void write_string(int *, u_int, struct sysctlnode *, char *, bool); |
133 | static void display_number(const struct sysctlnode *, const char *, | | 133 | static void display_number(const struct sysctlnode *, const char *, |
134 | const void *, size_t, int); | | 134 | const void *, size_t, int); |
135 | static void display_string(const struct sysctlnode *, const char *, | | 135 | static void display_string(const struct sysctlnode *, const char *, |
136 | const void *, size_t, int); | | 136 | const void *, size_t, int); |
137 | static void display_struct(const struct sysctlnode *, const char *, | | 137 | static void display_struct(const struct sysctlnode *, const char *, |
138 | const void *, size_t, int); | | 138 | const void *, size_t, int); |
139 | static void hex_dump(const unsigned char *, size_t); | | 139 | static void hex_dump(const unsigned char *, size_t); |
140 | __dead static void usage(void); | | 140 | __dead static void usage(void); |
141 | static void parse(char *, regex_t *, size_t *); | | 141 | static void parse(char *, regex_t *, size_t *); |
142 | static void parse_create(char *); | | 142 | static void parse_create(char *); |
143 | static void parse_destroy(char *); | | 143 | static void parse_destroy(char *); |
144 | static void parse_describe(char *); | | 144 | static void parse_describe(char *); |
145 | static void getdesc1(int *, u_int, struct sysctlnode *); | | 145 | static void getdesc1(int *, u_int, struct sysctlnode *); |
| @@ -936,30 +936,30 @@ parse(char *l, regex_t *re, size_t *last | | | @@ -936,30 +936,30 @@ parse(char *l, regex_t *re, size_t *last |
936 | } | | 936 | } |
937 | | | 937 | |
938 | switch (type) { | | 938 | switch (type) { |
939 | case CTLTYPE_NODE: | | 939 | case CTLTYPE_NODE: |
940 | /* | | 940 | /* |
941 | * XXX old behavior is to print. should we error instead? | | 941 | * XXX old behavior is to print. should we error instead? |
942 | */ | | 942 | */ |
943 | print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re, | | 943 | print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re, |
944 | lastcompiled); | | 944 | lastcompiled); |
945 | break; | | 945 | break; |
946 | case CTLTYPE_INT: | | 946 | case CTLTYPE_INT: |
947 | case CTLTYPE_BOOL: | | 947 | case CTLTYPE_BOOL: |
948 | case CTLTYPE_QUAD: | | 948 | case CTLTYPE_QUAD: |
949 | write_number(&name[0], namelen, node, value); | | 949 | write_number(&name[0], namelen, node, value, optional); |
950 | break; | | 950 | break; |
951 | case CTLTYPE_STRING: | | 951 | case CTLTYPE_STRING: |
952 | write_string(&name[0], namelen, node, value); | | 952 | write_string(&name[0], namelen, node, value, optional); |
953 | break; | | 953 | break; |
954 | case CTLTYPE_STRUCT: | | 954 | case CTLTYPE_STRUCT: |
955 | /* | | 955 | /* |
956 | * XXX old behavior is to print. should we error instead? | | 956 | * XXX old behavior is to print. should we error instead? |
957 | */ | | 957 | */ |
958 | /* fprintf(warnfp, "you can't write to %s\n", gsname); */ | | 958 | /* fprintf(warnfp, "you can't write to %s\n", gsname); */ |
959 | print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); | | 959 | print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); |
960 | break; | | 960 | break; |
961 | } | | 961 | } |
962 | } | | 962 | } |
963 | | | 963 | |
964 | /* | | 964 | /* |
965 | | | 965 | |
| @@ -1744,27 +1744,28 @@ sysctlperror(const char *fmt, ...) | | | @@ -1744,27 +1744,28 @@ sysctlperror(const char *fmt, ...) |
1744 | va_start(ap, fmt); | | 1744 | va_start(ap, fmt); |
1745 | (void)vfprintf(warnfp, fmt, ap); | | 1745 | (void)vfprintf(warnfp, fmt, ap); |
1746 | va_end(ap); | | 1746 | va_end(ap); |
1747 | errs++; | | 1747 | errs++; |
1748 | } | | 1748 | } |
1749 | | | 1749 | |
1750 | | | 1750 | |
1751 | /* | | 1751 | /* |
1752 | * ******************************************************************** | | 1752 | * ******************************************************************** |
1753 | * how to write to a "simple" node | | 1753 | * how to write to a "simple" node |
1754 | * ******************************************************************** | | 1754 | * ******************************************************************** |
1755 | */ | | 1755 | */ |
1756 | static void | | 1756 | static void |
1757 | write_number(int *name, u_int namelen, struct sysctlnode *node, char *value) | | 1757 | write_number(int *name, u_int namelen, struct sysctlnode *node, char *value, |
| | | 1758 | bool optional) |
1758 | { | | 1759 | { |
1759 | u_int ii, io; | | 1760 | u_int ii, io; |
1760 | u_quad_t qi, qo; | | 1761 | u_quad_t qi, qo; |
1761 | size_t si, so; | | 1762 | size_t si, so; |
1762 | bool bi, bo; | | 1763 | bool bi, bo; |
1763 | int rc; | | 1764 | int rc; |
1764 | void *i, *o; | | 1765 | void *i, *o; |
1765 | char *t; | | 1766 | char *t; |
1766 | | | 1767 | |
1767 | if (fn) | | 1768 | if (fn) |
1768 | trim_whitespace(value, 3); | | 1769 | trim_whitespace(value, 3); |
1769 | | | 1770 | |
1770 | si = so = 0; | | 1771 | si = so = 0; |
| @@ -1801,69 +1802,75 @@ write_number(int *name, u_int namelen, s | | | @@ -1801,69 +1802,75 @@ write_number(int *name, u_int namelen, s |
1801 | i = &bi; | | 1802 | i = &bi; |
1802 | si = sizeof(bi); | | 1803 | si = sizeof(bi); |
1803 | break; | | 1804 | break; |
1804 | case CTLTYPE_QUAD: | | 1805 | case CTLTYPE_QUAD: |
1805 | o = &qo; | | 1806 | o = &qo; |
1806 | so = sizeof(qo); | | 1807 | so = sizeof(qo); |
1807 | i = &qi; | | 1808 | i = &qi; |
1808 | si = sizeof(qi); | | 1809 | si = sizeof(qi); |
1809 | break; | | 1810 | break; |
1810 | } | | 1811 | } |
1811 | | | 1812 | |
1812 | rc = prog_sysctl(name, namelen, o, &so, i, si); | | 1813 | rc = prog_sysctl(name, namelen, o, &so, i, si); |
1813 | if (rc == -1) { | | 1814 | if (rc == -1) { |
1814 | sysctlerror(0); | | 1815 | if (!optional || errno != EPERM) { |
| | | 1816 | sysctlerror(0); |
| | | 1817 | } |
1815 | return; | | 1818 | return; |
1816 | } | | 1819 | } |
1817 | | | 1820 | |
1818 | switch (SYSCTL_TYPE(node->sysctl_flags)) { | | 1821 | switch (SYSCTL_TYPE(node->sysctl_flags)) { |
1819 | case CTLTYPE_INT: | | 1822 | case CTLTYPE_INT: |
1820 | display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD); | | 1823 | display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD); |
1821 | display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW); | | 1824 | display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW); |
1822 | break; | | 1825 | break; |
1823 | case CTLTYPE_BOOL: | | 1826 | case CTLTYPE_BOOL: |
1824 | display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD); | | 1827 | display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD); |
1825 | display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW); | | 1828 | display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW); |
1826 | break; | | 1829 | break; |
1827 | case CTLTYPE_QUAD: | | 1830 | case CTLTYPE_QUAD: |
1828 | display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD); | | 1831 | display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD); |
1829 | display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW); | | 1832 | display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW); |
1830 | break; | | 1833 | break; |
1831 | } | | 1834 | } |
1832 | } | | 1835 | } |
1833 | | | 1836 | |
1834 | static void | | 1837 | static void |
1835 | write_string(int *name, u_int namelen, struct sysctlnode *node, char *value) | | 1838 | write_string(int *name, u_int namelen, struct sysctlnode *node, char *value, |
| | | 1839 | bool optional) |
1836 | { | | 1840 | { |
1837 | char *i, *o; | | 1841 | char *i, *o; |
1838 | size_t si, so; | | 1842 | size_t si, so; |
1839 | int rc; | | 1843 | int rc; |
1840 | | | 1844 | |
1841 | i = value; | | 1845 | i = value; |
1842 | si = strlen(i) + 1; | | 1846 | si = strlen(i) + 1; |
1843 | so = node->sysctl_size; | | 1847 | so = node->sysctl_size; |
1844 | if (si > so && so != 0) { | | 1848 | if (si > so && so != 0) { |
1845 | sysctlperror("%s: string too long\n", value); | | 1849 | sysctlperror("%s: string too long\n", value); |
1846 | EXIT(EXIT_FAILURE); | | 1850 | EXIT(EXIT_FAILURE); |
1847 | } | | 1851 | } |
1848 | o = malloc(so); | | 1852 | o = malloc(so); |
1849 | if (o == NULL) { | | 1853 | if (o == NULL) { |
1850 | sysctlperror("%s: !malloc failed!\n", gsname); | | 1854 | sysctlperror("%s: !malloc failed!\n", gsname); |
1851 | exit(EXIT_FAILURE); | | 1855 | exit(EXIT_FAILURE); |
1852 | } | | 1856 | } |
1853 | | | 1857 | |
1854 | rc = prog_sysctl(name, namelen, o, &so, i, si); | | 1858 | rc = prog_sysctl(name, namelen, o, &so, i, si); |
1855 | if (rc == -1) { | | 1859 | if (rc == -1) { |
1856 | sysctlerror(0); | | 1860 | if (!optional || errno != EPERM) { |
| | | 1861 | sysctlerror(0); |
| | | 1862 | } |
| | | 1863 | free(o); |
1857 | return; | | 1864 | return; |
1858 | } | | 1865 | } |
1859 | | | 1866 | |
1860 | display_string(node, gsname, o, so, DISPLAY_OLD); | | 1867 | display_string(node, gsname, o, so, DISPLAY_OLD); |
1861 | display_string(node, gsname, i, si, DISPLAY_NEW); | | 1868 | display_string(node, gsname, i, si, DISPLAY_NEW); |
1862 | free(o); | | 1869 | free(o); |
1863 | } | | 1870 | } |
1864 | | | 1871 | |
1865 | /* | | 1872 | /* |
1866 | * ******************************************************************** | | 1873 | * ******************************************************************** |
1867 | * simple ways to print stuff consistently | | 1874 | * simple ways to print stuff consistently |
1868 | * ******************************************************************** | | 1875 | * ******************************************************************** |
1869 | */ | | 1876 | */ |