config: fix tilde expansion for wallpaper paths
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I45b7a520f1959886793ded62f1ed2cd96a6a6964
This commit is contained in:
parent
ca468ce677
commit
74fed80a26
3 changed files with 202 additions and 28 deletions
150
src/utils.c
150
src/utils.c
|
|
@ -94,18 +94,138 @@ void chroma_cleanup_signals(void) {
|
|||
g_config_file = NULL;
|
||||
}
|
||||
|
||||
// Expand tilde in path
|
||||
// Expand environment variables in a string
|
||||
static char *expand_env_vars(const char *str) {
|
||||
if (!str || strchr(str, '$') == NULL) {
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
char *result = strdup("");
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *p = str;
|
||||
while (*p) {
|
||||
if (*p == '$') {
|
||||
p++;
|
||||
if (*p == '{') {
|
||||
// ${VAR} format
|
||||
p++;
|
||||
const char *end = strchr(p, '}');
|
||||
if (!end) {
|
||||
// No closing brace, treat as literal
|
||||
char *tmp = realloc(result, strlen(result) + 2);
|
||||
if (!tmp) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result = tmp;
|
||||
strcat(result, "${");
|
||||
break;
|
||||
}
|
||||
|
||||
size_t var_len = end - p;
|
||||
char *var_name = malloc(var_len + 1);
|
||||
if (!var_name) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
strncpy(var_name, p, var_len);
|
||||
var_name[var_len] = '\0';
|
||||
|
||||
const char *var_value = getenv(var_name);
|
||||
if (var_value) {
|
||||
char *tmp = realloc(result, strlen(result) + strlen(var_value) + 1);
|
||||
if (!tmp) {
|
||||
free(var_name);
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result = tmp;
|
||||
strcat(result, var_value);
|
||||
}
|
||||
|
||||
free(var_name);
|
||||
p = end + 1;
|
||||
} else {
|
||||
// $VAR format
|
||||
const char *start = p;
|
||||
while (*p && (isalnum((unsigned char)*p) || *p == '_')) {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p == start) {
|
||||
// Not a valid variable name, treat $ as literal
|
||||
char *tmp = realloc(result, strlen(result) + 2);
|
||||
if (!tmp) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result = tmp;
|
||||
strcat(result, "$");
|
||||
} else {
|
||||
size_t var_len = p - start;
|
||||
char *var_name = malloc(var_len + 1);
|
||||
if (!var_name) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
strncpy(var_name, start, var_len);
|
||||
var_name[var_len] = '\0';
|
||||
|
||||
const char *var_value = getenv(var_name);
|
||||
if (var_value) {
|
||||
char *tmp = realloc(result, strlen(result) + strlen(var_value) + 1);
|
||||
if (!tmp) {
|
||||
free(var_name);
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result = tmp;
|
||||
strcat(result, var_value);
|
||||
}
|
||||
|
||||
free(var_name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Regular character
|
||||
size_t len = strlen(result);
|
||||
char *tmp = realloc(result, len + 2);
|
||||
if (!tmp) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result = tmp;
|
||||
result[len] = *p;
|
||||
result[len + 1] = '\0';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Expand tilde and environment variables in path
|
||||
char *chroma_expand_path(const char *path) {
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (path[0] != '~') {
|
||||
return strdup(path);
|
||||
// First expand environment variables
|
||||
char *env_expanded = expand_env_vars(path);
|
||||
if (!env_expanded) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Then expand tilde if present
|
||||
if (env_expanded[0] != '~') {
|
||||
return env_expanded;
|
||||
}
|
||||
|
||||
const char *home;
|
||||
if (path[1] == '/' || path[1] == '\0') {
|
||||
if (env_expanded[1] == '/' || env_expanded[1] == '\0') {
|
||||
// ~/... or just ~
|
||||
home = getenv("HOME");
|
||||
if (!home) {
|
||||
|
|
@ -116,34 +236,39 @@ char *chroma_expand_path(const char *path) {
|
|||
}
|
||||
if (!home) {
|
||||
chroma_log("ERROR", "Could not determine home directory");
|
||||
free(env_expanded);
|
||||
return strdup(path); // Return original path as fallback
|
||||
}
|
||||
|
||||
size_t home_len = strlen(home);
|
||||
size_t path_len = strlen(path);
|
||||
size_t path_len = strlen(env_expanded);
|
||||
char *expanded = malloc(home_len + path_len); // -1 for ~ +1 for \0
|
||||
if (!expanded) {
|
||||
chroma_log("ERROR", "Failed to allocate memory for path expansion");
|
||||
free(env_expanded);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
strcpy(expanded, home);
|
||||
if (path[1] == '/') {
|
||||
strcat(expanded, path + 1);
|
||||
if (env_expanded[1] == '/') {
|
||||
strcat(expanded, env_expanded + 1);
|
||||
}
|
||||
|
||||
free(env_expanded);
|
||||
return expanded;
|
||||
} else {
|
||||
// ~user/...
|
||||
const char *slash = strchr(path, '/');
|
||||
size_t user_len = slash ? (size_t)(slash - path - 1) : strlen(path) - 1;
|
||||
const char *slash = strchr(env_expanded, '/');
|
||||
size_t user_len =
|
||||
slash ? (size_t)(slash - env_expanded - 1) : strlen(env_expanded) - 1;
|
||||
|
||||
char *username = malloc(user_len + 1);
|
||||
if (!username) {
|
||||
free(env_expanded);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
strncpy(username, path + 1, user_len);
|
||||
strncpy(username, env_expanded + 1, user_len);
|
||||
username[user_len] = '\0';
|
||||
|
||||
struct passwd *pw = getpwnam(username);
|
||||
|
|
@ -151,6 +276,7 @@ char *chroma_expand_path(const char *path) {
|
|||
if (!pw) {
|
||||
chroma_log("ERROR", "User not found: %s", username);
|
||||
free(username);
|
||||
free(env_expanded);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +286,7 @@ char *chroma_expand_path(const char *path) {
|
|||
size_t remaining_len = slash ? strlen(slash) : 0;
|
||||
char *expanded = malloc(home_len + remaining_len + 1);
|
||||
if (!expanded) {
|
||||
free(env_expanded);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
|
|
@ -168,6 +295,7 @@ char *chroma_expand_path(const char *path) {
|
|||
strcat(expanded, slash);
|
||||
}
|
||||
|
||||
free(env_expanded);
|
||||
return expanded;
|
||||
}
|
||||
}
|
||||
|
|
@ -413,4 +541,4 @@ void chroma_format_memory_size(size_t bytes, char *buffer, size_t buffer_size) {
|
|||
}
|
||||
|
||||
// Cleanup utility functions
|
||||
void chroma_utils_cleanup(void) { chroma_cleanup_signals(); }
|
||||
void chroma_utils_cleanup(void) { chroma_cleanup_signals(); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue