/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #ifndef WIN32 // Goober5000 #include #include "globalincs/pstypes.h" #include "osapi/osregistry.h" #include "osapi/osapi.h" #include #include #include #include // ------------------------------------------------------------------------------------------------------------ // REGISTRY DEFINES/VARS // const char *Osreg_company_name = "Volition"; const char *Osreg_class_name = "FreeSpace2Class"; const char *Osreg_app_name = "FreeSpace2"; const char *Osreg_title = "FreeSpace 2"; #ifdef __APPLE__ const char *Osreg_user_dir = "Library/FS2_Open"; #else const char *Osreg_user_dir = ".fs2_open"; #endif // __APPLE__ #define PROFILE_NAME "fs2_open.ini" #define DEFAULT_SECTION "Default" typedef struct KeyValue { char *key; char *value; struct KeyValue *next; } KeyValue; typedef struct Section { char *name; struct KeyValue *pairs; struct Section *next; } Section; typedef struct Profile { struct Section *sections; } Profile; // ------------------------------------------------------------------------------------------------------------ // REGISTRY FUNCTIONS // static char *read_line_from_file(FILE *fp) { char *buf, *buf_start; int buflen, len, eol; buflen = 80; buf = (char *)vm_malloc(buflen); buf_start = buf; eol = 0; do { if (buf == NULL) { return NULL; } if (fgets(buf_start, 80, fp) == NULL) { if (buf_start == buf) { vm_free(buf); return NULL; } else { *buf_start = 0; return buf; } } len = strlen(buf_start); if (buf_start[len-1] == '\n') { buf_start[len-1] = 0; eol = 1; } else { buflen += 80; buf = (char *)vm_realloc(buf, buflen); /* be sure to skip over the proper amount of nulls */ buf_start = buf+(buflen-80)-(buflen/80)+1; } } while (!eol); return buf; } static char *trim_string(char *str) { char *ptr; int len; if (str == NULL) return NULL; /* kill any comment */ ptr = strchr(str, ';'); if (ptr) *ptr = 0; ptr = strchr(str, '#'); if (ptr) *ptr = 0; ptr = str; len = strlen(str); if (len > 0) { ptr += len-1; } while ((ptr > str) && isspace(*ptr)) { ptr--; } if (*ptr) { ptr++; *ptr = 0; } ptr = str; while (*ptr && isspace(*ptr)) { ptr++; } return ptr; } static Profile *profile_read(char *file) { char fullname[MAX_PATH_LEN]; FILE *fp = NULL; char *str; snprintf(fullname, MAX_PATH_LEN, "%s%s%s%s%s", detect_home(), DIR_SEPARATOR_STR, Osreg_user_dir, DIR_SEPARATOR_STR, file); fp = fopen(fullname, "rt"); if (fp == NULL) return NULL; Profile *profile = (Profile *)vm_malloc(sizeof(Profile)); profile->sections = NULL; Section **sp_ptr = &(profile->sections); Section *sp = NULL; KeyValue **kvp_ptr = NULL; while ((str = read_line_from_file(fp)) != NULL) { char *ptr = trim_string(str); if (*ptr == '[') { ptr++; char *pend = strchr(ptr, ']'); if (pend != NULL) { // if (pend[1]) { /* trailing garbage! */ } *pend = 0; if (*ptr) { sp = (Section *)vm_malloc(sizeof(Section)); sp->next = NULL; sp->name = vm_strdup(ptr); sp->pairs = NULL; *sp_ptr = sp; sp_ptr = &(sp->next); kvp_ptr = &(sp->pairs); } // else { /* null name! */ } } // else { /* incomplete section name! */ } } else { if (*ptr) { char *key = ptr; char *value = NULL; ptr = strchr(ptr, '='); if (ptr != NULL) { *ptr = 0; ptr++; value = ptr; } // else { /* random garbage! */ } if (key && *key && value /* && *value */) { if (sp != NULL) { KeyValue *kvp = (KeyValue *)vm_malloc(sizeof(KeyValue)); kvp->key = vm_strdup(key); kvp->value = vm_strdup(value); kvp->next = NULL; *kvp_ptr = kvp; kvp_ptr = &(kvp->next); } // else { /* key/value with no section! */ } // else { /* malformed key/value entry! */ } } // else it's just a comment or empty string } vm_free(str); } fclose(fp); return profile; } static void profile_free(Profile *profile) { if (profile == NULL) return; Section *sp = profile->sections; while (sp != NULL) { Section *st = sp; KeyValue *kvp = sp->pairs; while (kvp != NULL) { KeyValue *kvt = kvp; vm_free(kvp->key); vm_free(kvp->value); kvp = kvp->next; vm_free(kvt); } vm_free(sp->name); sp = sp->next; vm_free(st); } vm_free(profile); } static Profile *profile_update(Profile *profile, const char *section, const char *key, const char *value) { if (profile == NULL) { profile = (Profile *)vm_malloc(sizeof(Profile)); profile->sections = NULL; } KeyValue *kvp; Section **sp_ptr = &(profile->sections); Section *sp = profile->sections; while (sp != NULL) { if (strcmp(section, sp->name) == 0) { KeyValue **kvp_ptr = &(sp->pairs); kvp = sp->pairs; while (kvp != NULL) { if (strcmp(key, kvp->key) == 0) { vm_free(kvp->value); if (value == NULL) { *kvp_ptr = kvp->next; vm_free(kvp->key); vm_free(kvp); } else { kvp->value = vm_strdup(value); } /* all done */ return profile; } kvp_ptr = &(kvp->next); kvp = kvp->next; } if (value != NULL) { /* key not found */ kvp = (KeyValue *)vm_malloc(sizeof(KeyValue)); kvp->next = NULL; kvp->key = vm_strdup(key); kvp->value = vm_strdup(value); } *kvp_ptr = kvp; /* all done */ return profile; } sp_ptr = &(sp->next); sp = sp->next; } /* section not found */ sp = (Section *)vm_malloc(sizeof(Section)); sp->next = NULL; sp->name = vm_strdup(section); kvp = (KeyValue *)vm_malloc(sizeof(KeyValue)); kvp->next = NULL; kvp->key = vm_strdup(key); kvp->value = vm_strdup(value); sp->pairs = kvp; *sp_ptr = sp; return profile; } static char *profile_get_value(Profile *profile, const char *section, const char *key) { if (profile == NULL) return NULL; Section *sp = profile->sections; while (sp != NULL) { if (strcmp(section, sp->name) == 0) { KeyValue *kvp = sp->pairs; while (kvp != NULL) { if (strcmp(key, kvp->key) == 0) { return kvp->value; } kvp = kvp->next; } } sp = sp->next; } /* not found */ return NULL; } static void profile_save(Profile *profile, char *file) { FILE *fp = NULL; char tmp[MAX_PATH] = ""; char tmp2[MAX_PATH] = ""; char fullname[MAX_PATH_LEN]; if (profile == NULL) return; snprintf(fullname, MAX_PATH_LEN, "%s%s%s%s%s", detect_home(), DIR_SEPARATOR_STR, Osreg_user_dir, DIR_SEPARATOR_STR, file); fp = fopen(fullname, "wt"); if (fp == NULL) return; Section *sp = profile->sections; while (sp != NULL) { sprintf(tmp, NOX("[%s]\n"), sp->name); fputs(tmp, fp); KeyValue *kvp = sp->pairs; while (kvp != NULL) { sprintf(tmp2, NOX("%s=%s\n"), kvp->key, kvp->value); fputs(tmp2, fp); kvp = kvp->next; } fprintf(fp, "\n"); sp = sp->next; } fclose(fp); } // os registry functions ------------------------------------------------------------- static char szCompanyName[128]; static char szAppName[128]; static char szAppVersion[128]; int Os_reg_inited = 0; // initialize the registry. setup default keys to use void os_init_registry_stuff(const char *company, const char *app, const char *version) { if(company){ strcpy_s( szCompanyName, company ); } else { strcpy_s( szCompanyName, Osreg_company_name); } if(app){ strcpy_s( szAppName, app ); } else { strcpy_s( szAppName, Osreg_app_name); } if(version){ strcpy_s( szAppVersion, version); } else { strcpy_s( szAppVersion, "1.0"); } Os_reg_inited = 1; } static char tmp_string_data[1024]; const char *os_config_read_string(const char *section, const char *name, const char *default_value) { nprintf(( "Registry", "os_config_read_string(): section = \"%s\", name = \"%s\", default value: \"%s\"\n", (section) ? section : DEFAULT_SECTION, name, (default_value) ? default_value : NOX("NULL") )); Profile *p = profile_read(PROFILE_NAME); if (section == NULL) section = DEFAULT_SECTION; char *ptr = profile_get_value(p, section, name); if (ptr != NULL) { strncpy(tmp_string_data, ptr, 1023); default_value = tmp_string_data; } profile_free(p); return default_value; } unsigned int os_config_read_uint(const char *section, const char *name, unsigned int default_value) { Profile *p = profile_read(PROFILE_NAME); if (section == NULL) section = DEFAULT_SECTION; char *ptr = profile_get_value(p, section, name); if (ptr != NULL) { default_value = atoi(ptr); } profile_free(p); return default_value; } void os_config_write_string(const char *section, const char *name, const char *value) { Profile *p = profile_read(PROFILE_NAME); if (section == NULL) section = DEFAULT_SECTION; p = profile_update(p, section, name, value); profile_save(p, PROFILE_NAME); profile_free(p); } void os_config_write_uint(const char *section, const char *name, unsigned int value) { static char buf[21]; snprintf(buf, 20, "%u", value); Profile *p = profile_read(PROFILE_NAME); if (section == NULL) section = DEFAULT_SECTION; p = profile_update(p, section, name, buf); profile_save(p, PROFILE_NAME); profile_free(p); } #endif // Goober5000 - #ifndef WIN32