2 * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
15 #include <KernelExport.h>
17 #include <boot/kernel_args.h>
26 get_option_from_kernel_args(kernel_args
* args
, const char* settingsName
,
27 const char* parameter
, size_t parameterLength
, char* buffer
,
30 // find the settings in the kernel args
31 const char* settings
= NULL
;
32 for (driver_settings_file
* file
= args
->driver_settings
;
33 file
!= NULL
; file
= file
->next
) {
34 if (strcmp(settingsName
, file
->name
) == 0) {
35 settings
= file
->buffer
;
41 return B_ENTRY_NOT_FOUND
;
43 // Unfortunately we can't just use parse_driver_settings_string(), since
44 // we might not have a working heap yet. So we do very limited parsing
46 const char* settingsEnd
= settings
+ strlen(settings
);
47 int32 parameterLevel
= 0;
49 while (*settings
!= '\0') {
51 const char* lineEnd
= strchr(settings
, '\n');
54 nextLine
= lineEnd
+ 1;
56 nextLine
= lineEnd
= settingsEnd
;
58 // ignore any trailing comments
59 lineEnd
= std::find(settings
, lineEnd
, '#');
61 const char* nameStart
= NULL
;
62 const char* nameEnd
= NULL
;
63 const char* valueStart
= NULL
;
64 const char* valueEnd
= NULL
;
65 const char** elementEnd
= NULL
;
66 bool sawSeparator
= true;
68 for (; settings
< lineEnd
; settings
++) {
81 // TODO: That's not correct. There should be another loop.
86 if (parameterLevel
!= 0)
89 if (isspace(*settings
)) {
99 if (nameStart
== NULL
) {
100 nameStart
= settings
;
101 elementEnd
= &nameEnd
;
102 } else if (valueStart
== NULL
) {
103 valueStart
= settings
;
104 elementEnd
= &valueEnd
;
109 if (sawSeparator
&& elementEnd
!= NULL
) {
110 *elementEnd
= settings
;
115 if (elementEnd
!= NULL
)
116 *elementEnd
= settings
;
118 if (nameStart
!= NULL
&& size_t(nameEnd
- nameStart
) == parameterLength
119 && strncmp(parameter
, nameStart
, parameterLength
) == 0) {
120 if (valueStart
== NULL
)
121 return B_NAME_NOT_FOUND
;
123 size_t length
= valueEnd
- valueStart
;
124 if (*_bufferSize
> 0) {
125 size_t toCopy
= std::min(length
, *_bufferSize
- 1);
126 memcpy(buffer
, valueStart
, toCopy
);
127 buffer
[toCopy
] = '\0';
130 *_bufferSize
= length
;
137 return B_NAME_NOT_FOUND
;
141 #endif // !_BOOT_MODE
145 get_option(kernel_args
* args
, const char* settingsName
, const char* parameter
,
146 size_t parameterLength
, char* buffer
, size_t* _bufferSize
)
150 return get_option_from_kernel_args(args
, settingsName
, parameter
,
151 parameterLength
, buffer
, _bufferSize
);
155 void* handle
= load_driver_settings(settingsName
);
157 return B_ENTRY_NOT_FOUND
;
159 status_t status
= B_NAME_NOT_FOUND
;
161 const char* value
= get_driver_parameter(handle
, parameter
, NULL
, NULL
);
163 *_bufferSize
= strlcpy(buffer
, value
, *_bufferSize
);
167 unload_driver_settings(handle
);
173 get_option(kernel_args
* args
, const char* parameter
, char* buffer
,
176 size_t parameterLength
= strlen(parameter
);
177 status_t status
= get_option(args
, B_SAFEMODE_DRIVER_SETTINGS
, parameter
,
178 parameterLength
, buffer
, _bufferSize
);
179 if (status
!= B_OK
) {
180 // Try kernel settings file as a fall back
181 status
= get_option(args
, "kernel", parameter
, parameterLength
, buffer
,
190 get_boolean(kernel_args
* args
, const char* parameter
, bool defaultValue
)
193 size_t length
= sizeof(value
);
195 if (get_option(args
, parameter
, value
, &length
) != B_OK
)
198 return !strcasecmp(value
, "on") || !strcasecmp(value
, "true")
199 || !strcmp(value
, "1") || !strcasecmp(value
, "yes")
200 || !strcasecmp(value
, "enabled");
208 get_safemode_option(const char* parameter
, char* buffer
, size_t* _bufferSize
)
210 return get_option(NULL
, parameter
, buffer
, _bufferSize
);
215 get_safemode_boolean(const char* parameter
, bool defaultValue
)
217 return get_boolean(NULL
, parameter
, defaultValue
);
225 get_safemode_option_early(kernel_args
* args
, const char* parameter
,
226 char* buffer
, size_t* _bufferSize
)
228 return get_option(args
, parameter
, buffer
, _bufferSize
);
233 get_safemode_boolean_early(kernel_args
* args
, const char* parameter
,
236 return get_boolean(args
, parameter
, defaultValue
);
243 // #pragma mark - syscalls
250 _user_get_safemode_option(const char* userParameter
, char* userBuffer
,
251 size_t* _userBufferSize
)
253 char parameter
[B_FILE_NAME_LENGTH
];
254 char buffer
[B_PATH_NAME_LENGTH
];
255 size_t bufferSize
, originalBufferSize
;
257 if (!IS_USER_ADDRESS(userParameter
) || !IS_USER_ADDRESS(userBuffer
)
258 || !IS_USER_ADDRESS(_userBufferSize
)
259 || user_memcpy(&bufferSize
, _userBufferSize
, sizeof(size_t)) != B_OK
260 || user_strlcpy(parameter
, userParameter
, B_FILE_NAME_LENGTH
) < B_OK
)
261 return B_BAD_ADDRESS
;
263 if (bufferSize
> B_PATH_NAME_LENGTH
)
264 bufferSize
= B_PATH_NAME_LENGTH
;
266 originalBufferSize
= bufferSize
;
267 status_t status
= get_safemode_option(parameter
, buffer
, &bufferSize
);
270 && (user_strlcpy(userBuffer
, buffer
, originalBufferSize
) < B_OK
271 || user_memcpy(_userBufferSize
, &bufferSize
, sizeof(size_t))
273 return B_BAD_ADDRESS
;
279 #endif // !_BOOT_MODE