diff --git a/src/common/path.c b/src/common/path.c index e1b4c01..3f9fdf9 100644 --- a/src/common/path.c +++ b/src/common/path.c @@ -13,11 +13,14 @@ */ #include +#include #include "debug.h" #include "strbuf.h" #include "path.h" +static char path_null = '\0'; + /* * allocates and initilizes a path */ @@ -118,17 +121,33 @@ size_t pathlen(const char *path) { return size; } +static char* expand_home() { + + char *home = getenv("HOME"); + + if (!home) + home = &path_null; + return home; +} + char* path_normalize(const char *base, const char *name, unsigned char dir) { strbuf_t sb = STRBUF_INIT; - if (base == NULL || !is_abspath(base) || has_delim(name)) + if (base == NULL || has_delim(name)) return NULL; - strbuf_append_str(&sb, base); + if (*base == '~') { + base++; + strbuf_append_str(&sb, expand_home()); + strbuf_term(&sb, '/'); + } - if (sb.buf[sb.len] != '/') - strbuf_append_ch(&sb, '/'); + strbuf_append_str(&sb, base); + strbuf_term(&sb, '/'); + + if (!is_abspath(sb.buf)) + goto cleanup; if (name) { strbuf_append_str(&sb, name); @@ -140,4 +159,7 @@ char* path_normalize(const char *base, const char *name, unsigned char dir) { strbuf_squeeze(&sb, '/'); return strbuf_release(&sb); +cleanup: + strbuf_free(&sb); + return NULL; } diff --git a/test/t_path.c b/test/t_path.c index 1d1e478..dc46c98 100644 --- a/test/t_path.c +++ b/test/t_path.c @@ -1,6 +1,7 @@ #include #include +#include #include "unit.h" #include "../src/common/path.h" @@ -23,6 +24,14 @@ void test_normalize() { assert_string(ptr, "/stuff/with/ahell/lot/of/slashes/at/the/end/"); free(ptr); + ptr = path_normalize("~", NULL, 0); + printf("HOME EXPAND: %s\n", ptr); + free(ptr); + + ptr = path_normalize("~/sub", "file", 0); + printf("HOME EXPAND2: %s\n", ptr); + free(ptr); + ptr = path_normalize("/mnt/cdrom", "keff", 0); assert_string(ptr, "/mnt/cdrom/keff"); free(ptr);