1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <syscall.h>
7
8 #include <sys/sysctl.h>
9
10 typedef struct SysCtlEntry {
11 char path[64];
12 int type;
13 int flags;
14 char description[128];
15 } SysCtlEntry;
16
17 #define SYSCTL_STR(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
18 { #_PATH, SYSCTL_TYPE_STR, _FLAGS, _DESCRIPTION },
19 #define SYSCTL_INT(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
20 { #_PATH, SYSCTL_TYPE_INT, _FLAGS, _DESCRIPTION },
21 #define SYSCTL_BOOL(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
22 { #_PATH, SYSCTL_TYPE_BOOL, _FLAGS, _DESCRIPTION },
23 SysCtlEntry SYSCTLTable[] = {
24 SYSCTL_LIST
25 { "", 0, 0, "" },
26 };
27 #undef SYSCTL_STR
28 #undef SYSCTL_INT
29 #undef SYSCTL_BOOL
30
31 void
PrintVal(int idx)32 PrintVal(int idx)
33 {
34 switch (SYSCTLTable[idx].type) {
35 case SYSCTL_TYPE_STR: {
36 SysCtlString scStr;
37
38 OSSysCtl(SYSCTLTable[idx].path, &scStr, NULL);
39 printf("%s: %s\n", SYSCTLTable[idx].path, scStr.value);
40 break;
41 }
42 case SYSCTL_TYPE_INT: {
43 SysCtlInt scInt;
44
45 OSSysCtl(SYSCTLTable[idx].path, &scInt, NULL);
46 printf("%s: %ld\n", SYSCTLTable[idx].path, scInt.value);
47 break;
48 }
49 case SYSCTL_TYPE_BOOL: {
50 SysCtlBool scBool;
51
52 OSSysCtl(SYSCTLTable[idx].path, &scBool, NULL);
53 printf("%s: %s\n", SYSCTLTable[idx].path,
54 scBool.value ? "true" : "false");
55 break;
56 }
57 default:
58 printf("%s: Unsupported type\n", SYSCTLTable[idx].path);
59 break;
60 }
61 }
62
63 void
UpdateVal(int idx,const char * val)64 UpdateVal(int idx, const char *val)
65 {
66 switch (SYSCTLTable[idx].type) {
67 case SYSCTL_TYPE_STR: {
68 SysCtlString scStr;
69
70 strncpy(scStr.value, val, sizeof(scStr.value) - 1);
71 OSSysCtl(SYSCTLTable[idx].path, NULL, &scStr);
72 break;
73 }
74 case SYSCTL_TYPE_INT: {
75 SysCtlInt scInt;
76
77 scInt.value = atoi(val);
78 printf("%ld\n", scInt.value);
79 OSSysCtl(SYSCTLTable[idx].path, NULL, &scInt);
80 break;
81 }
82 case SYSCTL_TYPE_BOOL: {
83 SysCtlBool scBool;
84
85 if (strcmp(val,"true") == 0)
86 scBool.value = true;
87 else if (strcmp(val,"false") == 0)
88 scBool.value = false;
89 else {
90 printf("Value must be true or false\n");
91 exit(1);
92 }
93 OSSysCtl(SYSCTLTable[idx].path, NULL, &scBool);
94 break;
95 }
96 default:
97 printf("%s: Unsupported type\n", SYSCTLTable[idx].path);
98 break;
99 }
100 }
101
102 int
main(int argc,const char * argv[])103 main(int argc, const char *argv[])
104 {
105 if (argc == 2 && strcmp(argv[1],"-h") == 0) {
106 printf("Usage: sysctl [NODE] [VALUE]\n");
107 return 1;
108 }
109
110 if (argc == 2 && strcmp(argv[1],"-d") == 0) {
111 printf("%-20s %s\n", "Name", "Description");
112 for (int i = 0; SYSCTLTable[i].type != 0; i++) {
113 printf("%-20s %s\n",
114 SYSCTLTable[i].path,
115 SYSCTLTable[i].description);
116 }
117 return 0;
118 }
119
120 if (argc == 2 || argc == 3) {
121 for (int i = 0; SYSCTLTable[i].type != 0; i++) {
122 if (strcmp(SYSCTLTable[i].path, argv[1]) == 0) {
123 if (argc == 2)
124 PrintVal(i);
125 else
126 UpdateVal(i, argv[2]);
127 }
128 }
129
130 return 0;
131 }
132
133 for (int i = 0; SYSCTLTable[i].type != 0; i++) {
134 PrintVal(i);
135 }
136
137 return 0;
138 }
139
140