diff --git a/src/library.c b/src/library.c
index 23b3d6b..669dbf1 100644
--- a/src/library.c
+++ b/src/library.c
@@ -47,7 +47,7 @@ static void set_modified_time(Library_Entry *entry) {
static bool create_entry(struct dirent *dir_entry, const char *parent_path, Library_Entry *result) {
SV name = sv(dir_entry->d_name);
SV parent_path_sv = sv(parent_path);
- Noh_String full_path = build_path(false, &parent_path_sv, &name);
+ Noh_String full_path = build_path(false, false, &parent_path_sv, &name);
int type = dir_entry->d_type;
// Check if the entry is relevant.
diff --git a/src/opds_handler.c b/src/opds_handler.c
index a2a2bbf..50f7162 100644
--- a/src/opds_handler.c
+++ b/src/opds_handler.c
@@ -12,12 +12,12 @@ static void append_entry(Noh_String *response, SV url, Library_Entry entry) {
noh_string_append_cstr(response, noh_arena_sprintf(&temp, "%s", format_time(entry)));
if (entry.is_dir) {
SV opds = sv("opds");
- Noh_String entry_url = build_path(true, &opds, &url, &entry.name);
+ Noh_String entry_url = build_path(true, false, &opds, &url, &entry.name);
noh_string_append_cstr(response, noh_arena_sprintf(&temp, "", Nsv_Arg(entry_url)));
noh_string_free(&entry_url);
} else {
SV get = sv("get");
- Noh_String entry_url = build_path(true, &get, &url, &entry.name);
+ Noh_String entry_url = build_path(true, false, &get, &url, &entry.name);
noh_string_append_cstr(response, noh_arena_sprintf(&temp, "", Nsv_Arg(entry_url)));
noh_string_free(&entry_url);
}
@@ -34,7 +34,7 @@ static Noh_String create_feed_response(Library_Entry self_path, SV url, Library_
noh_string_append_cstr(&response, noh_arena_sprintf(&temp, "%s", format_time(self_path)));
SV opds = sv("opds");
- Noh_String self_url = build_path(true, &opds, &url);
+ Noh_String self_url = build_path(true, false, &opds, &url);
noh_string_append_cstr(&response, noh_arena_sprintf(&temp, "", Nsv_Arg(self_url)));
noh_string_free(&self_url);
diff --git a/src/path.c b/src/path.c
index 8075f50..431c514 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1,5 +1,5 @@
#define build_path(url, first, ...) build_path_((url), (first), __VA_ARGS__, NULL)
-static Noh_String build_path_(bool url, Noh_String_View *first, ...) {
+static Noh_String build_path_(bool url, bool go_up, Noh_String_View *first, ...) {
va_list args;
Noh_String_View *elem_ = first;
va_start(args, first);
@@ -11,7 +11,7 @@ static Noh_String build_path_(bool url, Noh_String_View *first, ...) {
Noh_String_View elem = *elem_;
while (elem.count > 0) {
Noh_String_View component = noh_sv_chop_by_delim(&elem, '/');
- if (noh_sv_eq(component, noh_sv_from_cstr(".."))) continue;
+ if (noh_sv_eq(component, noh_sv_from_cstr("..")) && !go_up) continue;
if (component.count > 0) {
if (start) start = false; else noh_string_append_cstr(&result, "/");
diff --git a/src/userctl.c b/src/userctl.c
index 047d701..2ba32c9 100644
--- a/src/userctl.c
+++ b/src/userctl.c
@@ -85,7 +85,7 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
// Read the file.
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
- Noh_String users_file_path = build_path(false, &library_path, &file_name);
+ Noh_String users_file_path = build_path(false, true, &library_path, &file_name);
noh_string_append_null(&users_file_path);
// Build users map.
@@ -114,7 +114,7 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
// Create user folder if needed.
- user_folder_path = build_path(false, &library_path, &username);
+ user_folder_path = build_path(false, true, &library_path, &username);
noh_string_append_null(&user_folder_path);
if (!noh_mkdir_if_needed(user_folder_path.elems)) noh_return_defer(false);
@@ -127,7 +127,7 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
// Create user folder if needed.
- user_folder_path = build_path(false, &library_path, &username);
+ user_folder_path = build_path(false, true, &library_path, &username);
noh_string_append_null(&user_folder_path);
if (!noh_mkdir_if_needed(user_folder_path.elems)) noh_return_defer(false);
@@ -145,7 +145,7 @@ bool delete_user(Noh_String_View library_path, Noh_String_View username) {
// Read the file.
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
- Noh_String users_file_path = build_path(false, &library_path, &file_name);
+ Noh_String users_file_path = build_path(false, true, &library_path, &file_name);
noh_string_append_null(&users_file_path);
// Build users map.
@@ -180,7 +180,7 @@ bool delete_user(Noh_String_View library_path, Noh_String_View username) {
if (!write_users_file(users_file_path.elems, &users, user_to_delete)) noh_return_defer(false);
// Prompt to delete the user's library folder.
- user_folder_path = build_path(false, &library_path, &username);
+ user_folder_path = build_path(false, true, &library_path, &username);
noh_string_append_null(&user_folder_path);
if (!noh_file_exists(user_folder_path.elems)) noh_return_defer(true);
@@ -200,7 +200,7 @@ defer:
bool list_users(Noh_String_View library_path) {
// Read the file.
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
- Noh_String users_file_path = build_path(false, &library_path, &file_name);
+ Noh_String users_file_path = build_path(false, true, &library_path, &file_name);
noh_string_append_null(&users_file_path);
// Build users map.