1 /*
2 * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <driver_settings.h>
8 #include <Directory.h>
9 #include <Entry.h>
10 #include <Path.h>
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16
17 bool gVerbose = false;
18
19 // Just add your test settings here, they will be picked
20 // up automatically
21
22 const char *kSettings[] = {
23 "keyA b c d {\n"
24 " keyB {\n"
25 " keyC d e f {\n"
26 " keyD e\n"
27 " keyE f\n"
28 " }\n"
29 " }}\n",
30
31 "keyA {\ndisabled\n}\n",
32
33 "keyA = b { keyB=d =e { keyC \"f g\"; keyD h } }"
34 };
35
36
37 // needed by the driver_settings implementation, but not part of
38 // the original R5 libroot.so
39
40 size_t
strnlen(char const * string,size_t count)41 strnlen(char const *string, size_t count)
42 {
43 const char *pos = string;
44
45 while (count-- && pos[0] != '\0')
46 pos++;
47
48 return pos - string;
49 }
50
51
52 /** Concatenates the source string to the destination, writes
53 * as much as "maxLength" bytes to the dest string.
54 * Always null terminates the string as long as maxLength is
55 * larger than the dest string.
56 * Returns the length of the string that it tried to create
57 * to be able to easily detect string truncation.
58 */
59
60 size_t
strlcat(char * dest,const char * source,size_t maxLength)61 strlcat(char *dest, const char *source, size_t maxLength)
62 {
63 size_t destLength = strnlen(dest, maxLength);
64
65 // This returns the wrong size, but it's all we can do
66 if (maxLength == destLength)
67 return destLength + strlen(source);
68
69 dest += destLength;
70 maxLength -= destLength;
71
72 size_t i = 0;
73 for (; i < maxLength - 1 && source[i]; i++) {
74 dest[i] = source[i];
75 }
76
77 dest[i] = '\0';
78
79 return destLength + i + strlen(source + i);
80 }
81
82
83 // #pragma mark -
84
85
86 void
put_level_space(int32 level)87 put_level_space(int32 level)
88 {
89 while (level-- > 0)
90 putchar('\t');
91 }
92
93
94 void
dump_parameter(const driver_parameter & parameter,int32 level)95 dump_parameter(const driver_parameter ¶meter, int32 level)
96 {
97 put_level_space(level);
98 printf("\"%s\" =", parameter.name);
99
100 for (int32 i = 0; i < parameter.value_count; i++)
101 printf(" \"%s\"", parameter.values[i]);
102 putchar('\n');
103
104 for (int32 i = 0; i < parameter.parameter_count; i++)
105 dump_parameter(parameter.parameters[i], level + 1);
106 }
107
108
109 void
dump_settings(const driver_settings & settings)110 dump_settings(const driver_settings &settings)
111 {
112 for (int32 i = 0; i < settings.parameter_count; i++)
113 dump_parameter(settings.parameters[i], 0);
114 }
115
116
117 void
print_settings(void * handle)118 print_settings(void *handle)
119 {
120 char buffer[2048];
121 size_t bufferSize = sizeof(buffer);
122
123 if (get_driver_settings_string(handle, buffer, &bufferSize, false) < B_OK) {
124 fprintf(stderr, "Could not get settings string (standard)\n");
125 exit(-1);
126 }
127 puts(" ----- standard");
128 puts(buffer);
129 puts(" ----- standard reparsed");
130
131 void *reparsedHandle = parse_driver_settings_string(buffer);
132 if (reparsedHandle == NULL) {
133 fprintf(stderr, "Could not reparse settings\n");
134 exit(-1);
135 }
136 const driver_settings *settings = get_driver_settings(reparsedHandle);
137 dump_settings(*settings);
138
139 unload_driver_settings(reparsedHandle);
140
141 bufferSize = sizeof(buffer);
142 if (get_driver_settings_string(handle, buffer, &bufferSize, true) < B_OK) {
143 fprintf(stderr, "Could not get settings string (flat)\n");
144 exit(-1);
145 }
146 puts(" ----- flat");
147 puts(buffer);
148 puts(" ----- flat reparsed");
149
150 reparsedHandle = parse_driver_settings_string(buffer);
151 if (reparsedHandle == NULL) {
152 fprintf(stderr, "Could not reparse settings\n");
153 exit(-1);
154 }
155 settings = get_driver_settings(reparsedHandle);
156 dump_settings(*settings);
157
158 unload_driver_settings(reparsedHandle);
159 }
160
161
162 void
check_settings_string(uint32 num)163 check_settings_string(uint32 num)
164 {
165 const char *string = kSettings[num];
166
167 printf("\n--------- settings %ld -----------\n", num);
168
169 void *handle = parse_driver_settings_string(string);
170 if (handle == NULL) {
171 fprintf(stderr, "Could not parse settings 1\n");
172 exit(-1);
173 }
174 const driver_settings *settings = get_driver_settings(handle);
175
176 if (gVerbose) {
177 puts(" ----- original");
178 puts(string);
179 puts(" ----- parsed");
180 dump_settings(*settings);
181 }
182
183 print_settings(handle);
184 unload_driver_settings(handle);
185 }
186
187
188 void
load_settings(const char * name)189 load_settings(const char *name)
190 {
191 void *handle = load_driver_settings(name);
192 if (handle == NULL) {
193 fprintf(stderr, "Could not load settings \"%s\"\n", name);
194 return;
195 }
196
197 const driver_settings *settings = get_driver_settings(handle);
198 if (settings == NULL) {
199 fprintf(stderr, "Could not get settings from loaded file \"%s\"\n", name);
200 goto end;
201 }
202
203 printf("settings \"%s\" loaded successfully\n", name);
204 if (gVerbose)
205 dump_settings(*settings);
206
207 end:
208 if (unload_driver_settings(handle) < B_OK)
209 fprintf(stderr, "Could not unload driver settings \"%s\"\n", name);
210 }
211
212
213 int
main(int argc,char ** argv)214 main(int argc, char **argv)
215 {
216 BDirectory directory("/boot/home/config/settings/kernel/drivers");
217 if (directory.InitCheck() != B_OK) {
218 fprintf(stderr, "Could not open directory: %s\n", strerror(directory.InitCheck()));
219 return 0;
220 }
221
222 // yes, I know I am lazy...
223 if (argc > 1 && !strcmp(argv[1], "-v"))
224 gVerbose = true;
225
226 entry_ref ref;
227 while (directory.GetNextRef(&ref) == B_OK) {
228 load_settings(ref.name);
229 }
230
231 // load additional files specified on the command line
232
233 for (int32 i = 1; i < argc; i++) {
234 const char *name = argv[i];
235 if (name[0] == '-')
236 continue;
237
238 // make path absolute, so that load_driver_settings()
239 // doesn't search in the standard directory
240 BPath path(name);
241 load_settings(path.Path());
242 }
243
244 // check fixed settings strings
245
246 for (uint32 i = 0; i < sizeof(kSettings) / sizeof(char *); i++)
247 check_settings_string(i);
248
249 return 0;
250 }
251
252