diff --git a/src/smol-http-pthreads.c b/src/smol-http-pthreads.c
index 0089e84..9672f2a 100644
--- a/src/smol-http-pthreads.c
+++ b/src/smol-http-pthreads.c
@@ -53,10 +53,10 @@ static void write_full(int ssl, const char *data, size_t len) {
}
}
-static void list_files(int ssl) {
+static void list_files(int ssl, char *directory) {
char buf[8192] = "
File ServerFiles
";
size_t pos = strlen(buf);
- DIR *dir = opendir(ROOT_DIR);
+ DIR *dir = opendir(directory);
if (!dir) {
send_response(ssl, "500 Internal Server Error", "text/plain", "Cannot open directory", 20);
return;
@@ -64,13 +64,14 @@ static void list_files(int ssl) {
struct dirent *entry;
while ((entry = readdir(dir)) && pos < sizeof(buf) - 100) {
- if (entry->d_name[0] == '.') continue;
+ if (!strcmp(entry->d_name, ".")) continue;
+ if (!strcmp(entry->d_name, "..") && !strcmp(directory, ROOT_DIR)) continue;
struct stat st;
char path[MAX_PATH];
- snprintf(path, sizeof(path), "%s/%s", ROOT_DIR, entry->d_name);
- if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
+ snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
+ // if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
pos += snprintf(buf + pos, sizeof(buf) - pos,
- "- %s
", entry->d_name, entry->d_name);
+ "- %s
", directory, entry->d_name, entry->d_name);
}
closedir(dir);
@@ -108,7 +109,7 @@ void *handle_request(void *param) {
}
if (!strcmp(path, "/")) {
- list_files(ssl);
+ list_files(ssl, ROOT_DIR);
close(ssl);
pthread_exit(0);
}
@@ -118,9 +119,14 @@ void *handle_request(void *param) {
struct stat st;
if (stat(file_path, &st) < 0 || S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st.st_mode)) {
+ list_files(ssl, file_path);
+ close(ssl);
+ pthread_exit(0);
+ }
send_response(ssl, st.st_mode ? "403 Forbidden" : "404 Not Found",
"text/plain", st.st_mode ? "Directory listing not allowed" : "Not Found",
- st.st_mode ? 28 : 9);
+ st.st_mode ? 29 : 9);
close(ssl);
pthread_exit(0);
}
diff --git a/src/smol-http.c b/src/smol-http.c
index 5696d07..61a7cca 100644
--- a/src/smol-http.c
+++ b/src/smol-http.c
@@ -47,10 +47,10 @@ static void write_full(int ssl, const char *data, size_t len) {
}
}
-static void list_files(int ssl) {
+static void list_files(int ssl, char *directory) {
char buf[8192] = "File ServerFiles
";
size_t pos = strlen(buf);
- DIR *dir = opendir(ROOT_DIR);
+ DIR *dir = opendir(directory);
if (!dir) {
send_response(ssl, "500 Internal Server Error", "text/plain", "Cannot open directory", 20);
return;
@@ -58,13 +58,14 @@ static void list_files(int ssl) {
struct dirent *entry;
while ((entry = readdir(dir)) && pos < sizeof(buf) - 100) {
- if (entry->d_name[0] == '.') continue;
+ if (!strcmp(entry->d_name, ".")) continue;
+ if (!strcmp(entry->d_name, "..") && !strcmp(directory, ROOT_DIR)) continue;
struct stat st;
char path[MAX_PATH];
- snprintf(path, sizeof(path), "%s/%s", ROOT_DIR, entry->d_name);
- if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
+ snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
+ // if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
pos += snprintf(buf + pos, sizeof(buf) - pos,
- "- %s
", entry->d_name, entry->d_name);
+ "- %s
", directory, entry->d_name, entry->d_name);
}
closedir(dir);
@@ -95,7 +96,7 @@ static void handle_request(int ssl, char *req) {
}
if (!strcmp(path, "/")) {
- list_files(ssl);
+ list_files(ssl, ROOT_DIR);
return;
}
@@ -104,9 +105,13 @@ static void handle_request(int ssl, char *req) {
struct stat st;
if (stat(file_path, &st) < 0 || S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st.st_mode)) {
+ list_files(ssl, file_path);
+ return;
+ }
send_response(ssl, st.st_mode ? "403 Forbidden" : "404 Not Found",
"text/plain", st.st_mode ? "Directory listing not allowed" : "Not Found",
- st.st_mode ? 28 : 9);
+ st.st_mode ? 29 : 9);
return;
}
diff --git a/src/smol-pthreads.c b/src/smol-pthreads.c
index 0bf33fa..5557b88 100644
--- a/src/smol-pthreads.c
+++ b/src/smol-pthreads.c
@@ -56,10 +56,10 @@ static void write_full(SSL *ssl, const char *data, size_t len) {
}
}
-static void list_files(SSL *ssl) {
+static void list_files(SSL *ssl, char *directory) {
char buf[8192] = "File ServerFiles
";
size_t pos = strlen(buf);
- DIR *dir = opendir(ROOT_DIR);
+ DIR *dir = opendir(directory);
if (!dir) {
send_response(ssl, "500 Internal Server Error", "text/plain", "Cannot open directory", 20);
return;
@@ -67,13 +67,13 @@ static void list_files(SSL *ssl) {
struct dirent *entry;
while ((entry = readdir(dir)) && pos < sizeof(buf) - 100) {
- if (entry->d_name[0] == '.') continue;
+ if (!strcmp(entry->d_name, ".")) continue;
+ if (!strcmp(entry->d_name, "..") && !strcmp(directory, ROOT_DIR)) continue;
struct stat st;
char path[MAX_PATH];
- snprintf(path, sizeof(path), "%s/%s", ROOT_DIR, entry->d_name);
- if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
+ snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
pos += snprintf(buf + pos, sizeof(buf) - pos,
- "- %s
", entry->d_name, entry->d_name);
+ "- %s
", directory, entry->d_name, entry->d_name);
}
closedir(dir);
@@ -120,7 +120,7 @@ void *handle_request(void *param) {
}
if (!strcmp(path, "/")) {
- list_files(ssl);
+ list_files(ssl, ROOT_DIR);
SSL_shutdown(ssl);
SSL_free(ssl);
close(client_sock);
@@ -132,9 +132,16 @@ void *handle_request(void *param) {
struct stat st;
if (stat(file_path, &st) < 0 || S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st.st_mode)) {
+ list_files(ssl, file_path);
+ SSL_shutdown(ssl);
+ SSL_free(ssl);
+ close(client_sock);
+ pthread_exit(0);
+ }
send_response(ssl, st.st_mode ? "403 Forbidden" : "404 Not Found",
"text/plain", st.st_mode ? "Directory listing not allowed" : "Not Found",
- st.st_mode ? 28 : 9);
+ st.st_mode ? 29 : 9);
SSL_shutdown(ssl);
SSL_free(ssl);
close(client_sock);
diff --git a/src/smol.c b/src/smol.c
index 7637b2d..d46937c 100644
--- a/src/smol.c
+++ b/src/smol.c
@@ -49,10 +49,10 @@ static void write_full(SSL *ssl, const char *data, size_t len) {
}
}
-static void list_files(SSL *ssl) {
+static void list_files(SSL *ssl, char *directory) {
char buf[8192] = "File ServerFiles
";
size_t pos = strlen(buf);
- DIR *dir = opendir(ROOT_DIR);
+ DIR *dir = opendir(directory);
if (!dir) {
send_response(ssl, "500 Internal Server Error", "text/plain", "Cannot open directory", 20);
return;
@@ -60,13 +60,14 @@ static void list_files(SSL *ssl) {
struct dirent *entry;
while ((entry = readdir(dir)) && pos < sizeof(buf) - 100) {
- if (entry->d_name[0] == '.') continue;
+ if (!strcmp(entry->d_name, ".")) continue;
+ if (!strcmp(entry->d_name, "..") && !strcmp(directory, ROOT_DIR)) continue;
struct stat st;
char path[MAX_PATH];
- snprintf(path, sizeof(path), "%s/%s", ROOT_DIR, entry->d_name);
- if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
+ snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
+ // if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) continue;
pos += snprintf(buf + pos, sizeof(buf) - pos,
- "- %s
", entry->d_name, entry->d_name);
+ "- %s
", directory, entry->d_name, entry->d_name);
}
closedir(dir);
@@ -97,7 +98,7 @@ static void handle_request(SSL *ssl, char *req) {
}
if (!strcmp(path, "/")) {
- list_files(ssl);
+ list_files(ssl, ROOT_DIR);
return;
}
@@ -106,9 +107,13 @@ static void handle_request(SSL *ssl, char *req) {
struct stat st;
if (stat(file_path, &st) < 0 || S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st.st_mode)) {
+ list_files(ssl, file_path);
+ return;
+ }
send_response(ssl, st.st_mode ? "403 Forbidden" : "404 Not Found",
"text/plain", st.st_mode ? "Directory listing not allowed" : "Not Found",
- st.st_mode ? 28 : 9);
+ st.st_mode ? 29 : 9);
return;
}