diff --git a/src/dcp.c b/src/dcp.c index 05abc76..bfd7d6f 100644 --- a/src/dcp.c +++ b/src/dcp.c @@ -3,35 +3,121 @@ #include #include #include +#include #include #include +#include #include #include #ifndef SYSCONFDIR #include "config.h" #endif -bool -find_calibration(size_t size, char *conffile, const char *sensor) +char * +mprintf(const char *fmt, ...) { - char model[512]; - int model_found = libmegapixels_get_model(sizeof(model), model); - if(!model_found) - return false; - static const char *paths[] = { - "config/%s,%s.dcp", - SYSCONFDIR "/megapixels/config/%s,%s.dcp", - DATADIR "/megapixels/config/%s,%s.dcp", - NULL - }; - for (const char **fmt = paths; *fmt; fmt++) { - snprintf(conffile, size, *fmt, model, sensor); + char *str = NULL; + va_list args; + va_start(args, fmt); + va_list args_copy; + va_copy(args_copy, args); + int len = vsnprintf(NULL, 0, fmt, args); + va_end(args); + if (len < 0) { + goto out; + } + str = malloc(len + 1); + if (str == NULL) { + goto out; + } + vsnprintf(str, len + 1, fmt, args_copy); +out: + va_end(args_copy); + return str; +} + +char * +mread(const char *path, long *size_out) +{ + FILE *src = fopen(path, "r"); + if (src == NULL) { + return NULL; + } + fseek(src, 0L, SEEK_END); + long src_size = ftell(src); + rewind(src); + char *data = malloc(src_size + 1); + if (data == NULL) { + return data; + } + fread(data, src_size, 1, src); + fclose(src); + data[src_size] = '\0'; + if (size_out != NULL) { + *size_out = src_size; + } + return data; +} + +bool +find_calibration_by_model(size_t maxlen, + char *conffile, + char *model, + const char *sensor) +{ + const char *home = getenv("HOME"); + char *config_home = getenv("XDG_CONFIG_HOME"); + int fch = 0; + if ((config_home == NULL || config_home[0] == '\0') && home != NULL) { + config_home = mprintf("%s/.config", home); + fch = 1; + } + // Check in XDG_CONFIG_HOME/megapixels/config + snprintf(conffile, + maxlen, + "%s/megapixels/config/%s.conf", + config_home, + model); + if (access(conffile, F_OK) != -1) { + if (fch) { + free(config_home); + } + return true; + } + + static const char *paths[] = { "config/%s,%s.dcp", + SYSCONFDIR "/megapixels/config/%s,%s.dcp", + DATADIR "/megapixels/config/%s,%s.dcp", + NULL }; + for (const char *fmt = paths[0]; fmt; fmt++) { + snprintf(conffile, maxlen, fmt, model, sensor); if (access(conffile, F_OK) != -1) { printf("Found calibration file at %s\n", conffile); return true; } } - printf("No calibration found for %s,%s\n", model, sensor); + return false; +} + +bool +find_calibration(size_t maxlen, char *conffile, const char *sensor) +{ + long size = 0; + char *compatible = mread("/proc/device-tree/compatible", &size); + if (compatible == NULL) { + return false; + } + + char *modelptr = compatible; + while ((modelptr - compatible) < size) { + if (find_calibration_by_model(maxlen, conffile, modelptr, sensor)) { + free(compatible); + return true; + } + modelptr += strlen(modelptr) + 1; + } + free(compatible); + printf("No calibration found %s\n", sensor); return false; }