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 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 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 87 put_level_space(int32 level) 88 { 89 while (level-- > 0) 90 putchar('\t'); 91 } 92 93 94 void 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 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 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 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 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 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