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