Login
1 branch 0 tags
Ben (Desktop/Arch) Limited podcast episode list to 16 entries b36bce8 29 days ago 80 Commits
moon / src / config.c
#include "config.h"
#include <string.h>
#include "storage.h"

#define CONFIG_BUF_SIZE 2048

// Extract value from: key = "value"
// Returns pointer past closing quote, or NULL on failure
static const char* extract_value(const char* line,
                                 const char* key,
                                 char* out,
                                 size_t out_size) {
	const char* p = strstr(line, key);
	if (!p) {
		return NULL;
	}
	p += strlen(key);

	// Skip whitespace and '='
	while (*p == ' ' || *p == '\t') {
		p++;
	}
	if (*p != '=') {
		return NULL;
	}
	p++;
	while (*p == ' ' || *p == '\t') {
		p++;
	}
	if (*p != '"') {
		return NULL;
	}
	p++;

	const char* end = strchr(p, '"');
	if (!end) {
		return NULL;
	}

	size_t len = (size_t)(end - p);
	if (len >= out_size) {
		len = out_size - 1;
	}
	memcpy(out, p, len);
	out[len] = '\0';
	return end + 1;
}

bool config_load(config_t* cfg) {
	if (!cfg) {
		return false;
	}
	memset(cfg, 0, sizeof(*cfg));

	storage_file_t f = storage_open(CONFIG_FILE, "r");
	if (!f) {
		return false;
	}

	char buf[CONFIG_BUF_SIZE];
	size_t n = storage_read(f, buf, sizeof(buf) - 1);
	storage_close(f);
	buf[n] = '\0';

	bool in_wifi = false;

	char* line = buf;
	while (line && *line) {
		char* eol = strchr(line, '\n');
		if (eol) {
			*eol = '\0';
		}

		// Skip leading whitespace
		char* p = line;
		while (*p == ' ' || *p == '\t') {
			p++;
		}

		if (strncmp(p, "[[wifi]]", 8) == 0) {
			in_wifi = true;
			if (cfg->wifi_count < CONFIG_MAX_WIFI) {
				cfg->wifi_count++;
			}
		} else if (p[0] == '[') {
			in_wifi = false;
		} else if (in_wifi && cfg->wifi_count > 0 &&
		           cfg->wifi_count <= CONFIG_MAX_WIFI) {
			wifi_config_entry_t* entry = &cfg->wifi[cfg->wifi_count - 1];
			if (strncmp(p, "ssid", 4) == 0) {
				extract_value(p, "ssid", entry->ssid, sizeof(entry->ssid));
			} else if (strncmp(p, "psk", 3) == 0) {
				extract_value(p, "psk", entry->psk, sizeof(entry->psk));
			}
		}

		if (!eol) {
			break;
		}
		line = eol + 1;
	}

	return cfg->wifi_count > 0;
}