$OpenBSD: patch-src_config_c,v 1.4 2011/03/14 12:55:18 dcoppa Exp $ --- src/config.c.orig Wed Jan 19 21:26:37 2011 +++ src/config.c Thu Mar 10 14:23:42 2011 @@ -18,7 +18,6 @@ #include #include #include -#include #include /* We need Xlib for XStringToKeysym */ @@ -39,27 +38,34 @@ struct modes_head modes; /* * This function resolves ~ in pathnames. + * It may resolve wildcards in the first part of the path, but if no match + * or multiple matches are found, it just returns a copy of path as given. * */ -char *glob_path(const char *path) { +char *resolve_tilde(const char *path) { static glob_t globbuf; - if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) + char *head, *tail, *result; + + tail = strchr(path, '/'); + head = strndup(path, tail ? tail - path : strlen(path)); + + int res = glob(head, GLOB_TILDE, NULL, &globbuf); + free(head); + /* no match, or many wildcard matches are bad */ + if(res == GLOB_NOMATCH || globbuf.gl_pathc != 1) + result = strdup(path); + else if (res != 0) { die("glob() failed"); - char *result = sstrdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path); + result = NULL; /* don't complain about uninitialized */ + } + else { + head = globbuf.gl_pathv[0]; + result = malloc(strlen(head) + (tail ? strlen(tail) : 0) + 1); + strncpy(result, head, strlen(head)+1); + strncat(result, tail, strlen(tail)); + } globfree(&globbuf); - /* If the file does not exist yet, we still may need to resolve tilde, - * so call wordexp */ - if (strcmp(result, path) == 0) { - wordexp_t we; - wordexp(path, &we, WRDE_NOCMD); - if (we.we_wordc > 0) { - free(result); - result = sstrdup(we.we_wordv[0]); - } - wordfree(&we); - } - return result; } @@ -239,7 +245,7 @@ static char *get_config_path() { if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) xdg_config_home = "~/.config"; - xdg_config_home = glob_path(xdg_config_home); + xdg_config_home = resolve_tilde(xdg_config_home); if (asprintf(&config_path, "%s/i3/config", xdg_config_home) == -1) die("asprintf() failed"); free(xdg_config_home); @@ -250,12 +256,12 @@ static char *get_config_path() { /* 2: check for $XDG_CONFIG_DIRS/i3/config */ if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) - xdg_config_dirs = "/etc/xdg"; + xdg_config_dirs = "${SYSCONFDIR}/xdg"; char *buf = sstrdup(xdg_config_dirs); char *tok = strtok(buf, ":"); while (tok != NULL) { - tok = glob_path(tok); + tok = resolve_tilde(tok); if (asprintf(&config_path, "%s/i3/config", tok) == -1) die("asprintf() failed"); free(tok); @@ -269,15 +275,15 @@ static char *get_config_path() { free(buf); /* 3: check traditional paths */ - config_path = glob_path("~/.i3/config"); + config_path = resolve_tilde("~/.i3/config"); if (path_exists(config_path)) return config_path; - config_path = sstrdup("/etc/i3/config"); + config_path = sstrdup("${SYSCONFDIR}/i3/config"); if (!path_exists(config_path)) die("Neither $XDG_CONFIG_HOME/i3/config, nor " "$XDG_CONFIG_DIRS/i3/config, nor ~/.i3/config nor " - "/etc/i3/config exist."); + "${SYSCONFDIR}/i3/config exist."); return config_path; }