Remove useless stuff (was thing for RTL transposition only, which will not be impleme...
[open-ps2-loader.git] / src / config.c
blobb569d91b6a7e3a55b1480886fbc50939bd1174d2
1 /*
2 Copyright 2009, Ifcaro & volca
3 Licenced under Academic Free License version 3.0
4 Review OpenUsbLd README & LICENSE files for further details.
5 */
7 #include "include/usbld.h"
8 #include "include/util.h"
9 #include "include/ioman.h"
10 #include <string.h>
12 #define CONFIG_INDEX_OPL 0
13 #define CONFIG_INDEX_LAST 1
14 #define CONFIG_INDEX_APPS 2
15 #define CONFIG_INDEX_VMODE 3
17 static config_set_t configFiles[CONFIG_FILE_NUM];
18 static char configPath[255] = "mc?:SYS-CONF/IPCONFIG.DAT";
20 static int strToColor(const char *string, unsigned char *color) {
21 int cnt=0, n=0;
22 color[0]=0;
23 color[1]=0;
24 color[2]=0;
26 if (!string || !*string) return 0;
27 if (string[0]!='#') return 0;
29 string++;
31 while (*string) {
32 int fh = fromHex(*string);
33 if (fh >= 0) {
34 color[n] = color[n] * 16 + fh;
35 } else {
36 break;
39 // Two characters per color
40 if(cnt==1) {
41 cnt=0;
42 n++;
43 }else{
44 cnt++;
47 string++;
50 return 1;
53 /// true if given a whitespace character
54 int isWS(char c) {
55 return c == ' ' || c == '\t';
58 static int splitAssignment(char* line, char* key, size_t keymax, char* val, size_t valmax) {
59 // skip whitespace
60 for (;isWS(*line); ++line);
62 // find "=".
63 // If found, the text before is key, after is val.
64 // Otherwise malformed string is encountered
66 char* eqpos = strchr(line, '=');
68 if (eqpos) {
69 // copy the name and the value
70 size_t keylen = min(keymax, eqpos - line);
72 strncpy(key, line, keylen);
74 eqpos++;
76 size_t vallen = min(valmax, strlen(line) - (eqpos - line));
77 strncpy(val, eqpos, vallen);
80 return (int) eqpos;
83 static int parsePrefix(char* line, char* prefix) {
84 // find "=".
85 // If found, the text before is key, after is val.
86 // Otherwise malformed string is encountered
87 char* colpos = strchr(line, ':');
89 if (colpos && colpos != line) {
90 // copy the name and the value
91 strncpy(prefix, line, colpos - line);
93 return 1;
94 } else {
95 return 0;
99 static int configKeyValidate(const char* key) {
100 if (strlen(key) == 0)
101 return 0;
103 return !strchr(key, '=');
106 static struct config_value_t* allocConfigItem(const char* key, const char* val) {
107 struct config_value_t* it = (struct config_value_t*) malloc(sizeof(struct config_value_t));
108 strncpy(it->key, key, 32);
109 it->key[min(strlen(key), 31)] = '\0';
110 strncpy(it->val, val, 255);
111 it->val[min(strlen(val), 254)] = '\0';
112 it->next = NULL;
114 return it;
117 /// Low level key addition. Does not check for uniqueness.
118 static void addConfigValue(config_set_t* configSet, const char* key, const char* val) {
119 if (!configSet->tail) {
120 configSet->head = allocConfigItem(key, val);
121 configSet->tail = configSet->head;
122 } else {
123 configSet->tail->next = allocConfigItem(key, val);
124 configSet->tail = configSet->tail->next;
128 static struct config_value_t* getConfigItemForName(config_set_t* configSet, const char* name) {
129 struct config_value_t* val = configSet->head;
131 while (val) {
132 if (strncmp(val->key, name, 32) == 0)
133 break;
135 val = val->next;
138 return val;
141 void configInit(char *prefix) {
142 char path[255];
144 if (prefix)
145 snprintf(configPath, 255, "%s/IPCONFIG.DAT", prefix);
146 else
147 prefix = gBaseMCDir;
149 snprintf(path, 255, "%s/conf_opl.cfg", prefix);
150 configAlloc(CONFIG_OPL, &configFiles[CONFIG_INDEX_OPL], path);
151 snprintf(path, 255, "%s/conf_last.cfg", prefix);
152 configAlloc(CONFIG_LAST, &configFiles[CONFIG_INDEX_LAST], path);
153 snprintf(path, 255, "%s/conf_apps.cfg", prefix);
154 configAlloc(CONFIG_APPS, &configFiles[CONFIG_INDEX_APPS], path);
155 snprintf(path, 255, "%s/conf_vmode.cfg", prefix);
156 configAlloc(CONFIG_VMODE, &configFiles[CONFIG_INDEX_VMODE], path);
159 void configEnd() {
160 int index = 0;
161 while(index < CONFIG_FILE_NUM) {
162 config_set_t *configSet = &configFiles[index];
164 configClear(configSet);
165 free(configSet->filename);
166 configSet->filename = NULL;
167 index++;
171 config_set_t *configAlloc(int type, config_set_t *configSet, char *fileName) {
172 if (!configSet)
173 configSet = (config_set_t*) malloc(sizeof(config_set_t));
175 configSet->type = type;
176 configSet->head = NULL;
177 configSet->tail = NULL;
178 if (fileName) {
179 int length = strlen(fileName) + 1;
180 configSet->filename = (char*) malloc(length * sizeof(char));
181 memcpy(configSet->filename, fileName, length);
182 } else
183 configSet->filename = NULL;
184 configSet->modified = 0;
185 return configSet;
188 void configFree(config_set_t *configSet) {
189 configClear(configSet);
190 free(configSet->filename);
191 free(configSet);
192 configSet = NULL;
195 config_set_t *configGetByType(int type) {
196 int index = 0;
197 while(index < CONFIG_FILE_NUM) {
198 config_set_t *configSet = &configFiles[index];
200 if (configSet->type == type)
201 return configSet;
202 index++;
204 return NULL;
207 int configSetStr(config_set_t* configSet, const char* key, const char* value) {
208 if (!configKeyValidate(key))
209 return 0;
211 struct config_value_t *it = getConfigItemForName(configSet, key);
213 if (it) {
214 if (strncmp(it->val, value, 255) != 0) {
215 strncpy(it->val, value, 255);
216 it->val[min(strlen(value), 254)] = '\0';
217 if (it->key[0] != '#')
218 configSet->modified = 1;
220 } else {
221 addConfigValue(configSet, key, value);
222 if (key[0] != '#')
223 configSet->modified = 1;
226 return 1;
229 // sets the value to point to the value str in the config. Do not overwrite - it will overwrite the string in config
230 int configGetStr(config_set_t* configSet, const char* key, char** value) {
231 if (!configKeyValidate(key))
232 return 0;
234 struct config_value_t *it = getConfigItemForName(configSet, key);
236 if (it) {
237 *value = it->val;
238 return 1;
239 } else
240 return 0;
243 void configGetStrCopy(config_set_t* configSet, const char* key, char* value) {
244 char *valref = NULL;
245 if (configGetStr(configSet, key, &valref))
246 strncpy(value, valref, 32);
247 else
248 value[0] = '\0';
251 int configSetInt(config_set_t* configSet, const char* key, const int value) {
252 char tmp[12];
253 snprintf(tmp, 12, "%d", value);
254 return configSetStr(configSet, key, tmp);
257 int configGetInt(config_set_t* configSet, const char* key, int* value) {
258 char *valref = NULL;
259 if (configGetStr(configSet, key, &valref)) {
260 *value = atoi(valref);
261 return 1;
262 } else {
263 return 0;
267 int configSetColor(config_set_t* configSet, const char* key, unsigned char* color) {
268 char tmp[8];
269 snprintf(tmp, 8, "#%02X%02X%02X", color[0], color[1], color[2]);
270 return configSetStr(configSet, key, tmp);
273 int configGetColor(config_set_t* configSet, const char* key, unsigned char* color) {
274 char *valref = NULL;
275 if (configGetStr(configSet, key, &valref)) {
276 strToColor(valref, color);
277 return 1;
278 } else {
279 return 0;
283 int configRemoveKey(config_set_t* configSet, const char* key) {
284 if (!configKeyValidate(key))
285 return 0;
287 struct config_value_t* val = configSet->head;
288 struct config_value_t* prev = NULL;
290 while (val) {
291 if (strncmp(val->key, key, 32) == 0) {
292 if (key[0] != '#')
293 configSet->modified = 1;
295 if (val == configSet->tail)
296 configSet->tail = prev;
298 val = val->next;
299 if (prev) {
300 free(prev->next);
301 prev->next = val;
303 else {
304 free(configSet->head);
305 configSet->head = val;
307 } else {
308 prev = val;
309 val = val->next;
313 return 1;
316 void configReadIP() {
317 int fd = openFile(configPath, O_RDONLY);
318 if (fd >= 0) {
319 char ipconfig[255];
320 int size = getFileSize(fd);
321 fioRead(fd, &ipconfig, size);
322 fioClose(fd);
324 sscanf(ipconfig, "%d.%d.%d.%d %d.%d.%d.%d %d.%d.%d.%d", &ps2_ip[0], &ps2_ip[1], &ps2_ip[2], &ps2_ip[3],
325 &ps2_netmask[0], &ps2_netmask[1], &ps2_netmask[2], &ps2_netmask[3],
326 &ps2_gateway[0], &ps2_gateway[1], &ps2_gateway[2], &ps2_gateway[3]);
329 return;
332 void configWriteIP() {
333 int fd = openFile(configPath, O_WRONLY | O_CREAT);
334 if (fd >= 0) {
335 char ipconfig[255];
336 sprintf(ipconfig, "%d.%d.%d.%d %d.%d.%d.%d %d.%d.%d.%d\r\n", ps2_ip[0], ps2_ip[1], ps2_ip[2], ps2_ip[3],
337 ps2_netmask[0], ps2_netmask[1], ps2_netmask[2], ps2_netmask[3],
338 ps2_gateway[0], ps2_gateway[1], ps2_gateway[2], ps2_gateway[3]);
340 fioWrite(fd, ipconfig, strlen(ipconfig));
341 fioClose(fd);
345 // dst has to have 5 bytes space
346 void configGetDiscIDBinary(config_set_t* configSet, void* dst) {
347 memset(dst, 0, 5);
349 char *gid = NULL;
350 if (configGetStr(configSet, CONFIG_ITEM_DNAS, &gid)) {
351 // convert from hex to binary
352 char* cdst = dst;
353 int p = 0;
354 while (*gid && p < 10) {
355 int dv = -1;
357 while (dv < 0 && *gid) // skip spaces, etc
358 dv = fromHex(*(gid++));
360 if (dv < 0)
361 break;
363 *cdst = *cdst * 16 + dv;
364 if ((++p & 1) == 0)
365 cdst++;
370 int configRead(config_set_t* configSet) {
371 file_buffer_t* fileBuffer = openFileBuffer(configSet->filename, O_RDONLY, 0, 4096);
372 if (!fileBuffer) {
373 LOG("No config %s.\n", configSet->filename);
374 configSet->modified = 0;
375 return 0;
378 char* line;
379 unsigned int lineno = 0;
381 char prefix[32];
382 memset(prefix, 0, sizeof(prefix));
384 while (readFileBuffer(fileBuffer, &line)) {
385 lineno++;
387 char key[32], val[255];
388 memset(key, 0, sizeof(key));
389 memset(val, 0, sizeof(val));
391 if (splitAssignment(line, key, sizeof(key), val, sizeof(val))) {
392 /* if the line does not start with whitespace,
393 * the prefix ends and we have to reset it
395 if (!isWS(line[0]))
396 memset(prefix, 0, sizeof(prefix));
398 // insert config value
399 if (prefix[0]) {
400 // we have a prefix
401 char composedKey[66];
403 snprintf(composedKey, 65, "%s_%s", prefix, key);
404 composedKey[65] = '\0';
406 configSetStr(configSet, composedKey, val);
407 } else {
408 configSetStr(configSet, key, val);
410 } else if (parsePrefix(line, prefix)) {
411 // prefix is set, that's about it
412 } else {
413 LOG("Malformed config file '%s' line %d: '%s'\n", configSet->filename, lineno, line);
416 closeFileBuffer(fileBuffer);
417 configSet->modified = 0;
418 return configSet->type;
421 int configWrite(config_set_t* configSet) {
422 if (configSet->modified) {
423 // BUG in PFS: O_TRUNC doesn't work, so we remove the file and re-create it
424 if (strncmp(configSet->filename, "pfs0:", 5) == 0)
425 fioRemove(configSet->filename);
427 file_buffer_t* fileBuffer = openFileBuffer(configSet->filename, O_WRONLY | O_CREAT | O_TRUNC, 0, 4096);
428 if (fileBuffer) {
429 char line[512];
431 struct config_value_t* cur = configSet->head;
432 while (cur) {
433 if ((cur->key[0] != '\0') && (cur->key[0] != '#')) {
434 snprintf(line, 512, "%s=%s\r\n", cur->key, cur->val); // add windows CR+LF (0x0D 0x0A)
435 writeFileBuffer(fileBuffer, line, strlen(line));
438 // and advance
439 cur = cur->next;
442 closeFileBuffer(fileBuffer);
443 configSet->modified = 0;
444 return 1;
446 return 0;
448 return 1;
451 void configClear(config_set_t* configSet) {
452 while (configSet->head) {
453 struct config_value_t* cur = configSet->head;
454 configSet->head = cur->next;
456 free(cur);
459 configSet->head = NULL;
460 configSet->tail = NULL;
461 configSet->modified = 1;
464 int configReadMulti(int types) {
465 int result = 0;
467 if (CONFIG_OPL & types)
468 configReadIP();
470 int index = 0;
471 while(index < CONFIG_FILE_NUM) {
472 config_set_t *configSet = &configFiles[index];
474 if (configSet->type & types) {
475 configClear(configSet);
476 result |= configRead(configSet);
478 index++;
481 return result;
484 int configWriteMulti(int types) {
485 int result = 0;
487 if ((CONFIG_OPL & types) && gIPConfigChanged)
488 configWriteIP();
490 int index = 0;
491 while(index < CONFIG_FILE_NUM) {
492 config_set_t *configSet = &configFiles[index];
494 if (configSet->type & types)
495 result += configWrite(configSet);
496 index++;
499 return result;
502 #ifdef VMC
503 void configGetVMC(config_set_t* configSet, char* vmc, int slot) {
504 char *valref = NULL;
505 char gkey[255];
506 snprintf(gkey, 255, "%s_%d", CONFIG_ITEM_VMC, slot);
507 if (configGetStr(configSet, gkey, &valref))
508 strncpy(vmc, valref, 32);
509 else
510 vmc[0] = '\0';
513 void configSetVMC(config_set_t* configSet, const char* vmc, int slot) {
514 char gkey[255];
515 if(vmc[0] == '\0') {
516 configRemoveVMC(configSet, slot);
517 return;
519 snprintf(gkey, 255, "%s_%d", CONFIG_ITEM_VMC, slot);
520 configSetStr(configSet, gkey, vmc);
523 void configRemoveVMC(config_set_t* configSet, int slot) {
524 char gkey[255];
525 snprintf(gkey, 255, "%s_%d", CONFIG_ITEM_VMC, slot);
526 configRemoveKey(configSet, gkey);
528 #endif