From: Andrea Zagli <azagli@libero.it>
Date: Sun, 24 Sep 2017 09:36:26 +0000 (+0200)
Subject: Directory browsing.
X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=e628d0d4c2aa9f9d706406f7ac5a8c2f2ea976d3;p=zakjukebox

Directory browsing.
---

diff --git a/src/index.c b/src/index.c
index f1d4b02..7411f28 100644
--- a/src/index.c
+++ b/src/index.c
@@ -20,6 +20,8 @@
 	#include <config.h>
 #endif
 
+#include <string.h>
+
 #include <tmpl-glib.h>
 
 #include "index.h"
@@ -27,8 +29,8 @@
 static gchar
 *render_dir (Commons *commons, const gchar *dir)
 {
-	g_autoptr (GError) error = NULL;
-	g_autoptr (GFile) gfdir = NULL;
+	GError *error;
+	g_autoptr (GFile) gfdir;
 	g_autoptr (GFileEnumerator) gfenum = NULL;
 
 	g_autoptr (GString) ret;
@@ -41,40 +43,64 @@ static gchar
 	g_string_append_printf (ret, "<h1>%s</h1>\n", path);
 	g_string_append (ret, "<ul>\n");
 
+	if (g_strcmp0 (dir, "") != 0)
+		{
+			g_string_append (ret, "<li><a href=\"/zakjukebox/index/cd/{up}\">..</a></li>\n");
+		}
+
 	gfdir = g_file_new_for_path (path);
 	if (g_file_query_file_type (gfdir, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY)
 		{
 			error = NULL;
-			gfenum = g_file_enumerate_children (gfdir, NULL, G_FILE_QUERY_INFO_NONE, NULL, &error);
-			if (gfenum == NULL)
+			gfenum = g_file_enumerate_children (gfdir, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NONE, NULL, &error);
+			if (gfenum == NULL
+			    || error != NULL)
 				{
 					g_warning ("Error on directory enumeration: %s", error->message);
-					return "";
+					g_string_append_printf (ret, "Error: %s", error->message);
 				}
-
-			while (TRUE)
+			else
 				{
-					g_autoptr (GFile) gf = NULL;
-					g_autoptr (GFileInfo) gfi = NULL;
-
-					error = NULL;
-					if (!g_file_enumerator_iterate (gfenum, &gfi, &gf, NULL, &error))
+					while (TRUE)
 						{
-							g_warning ("Error on reading file: %s", error->message);
-							continue;
-						}
-					if (gf == NULL)
-						{
-							break;
-						}
-
-					GFileType gft;
-
-					gft = g_file_info_get_file_type (gfi);
-					if (gft == G_FILE_TYPE_DIRECTORY
-					    || gft == G_FILE_TYPE_REGULAR)
-						{
-							g_string_append_printf (ret, "<li>%s</li>\n", g_file_get_basename (gf));
+							GFile *gf;
+							GFileInfo *gfi;
+
+							gf = NULL;
+							gfi = NULL;
+
+							if (error != NULL)
+								{
+									g_object_unref (error);
+									error = NULL;
+								}
+							if (!g_file_enumerator_iterate (gfenum, &gfi, &gf, NULL, &error))
+								{
+									g_warning ("Error on reading file: %s", error->message);
+									continue;
+								}
+							if (gfi == NULL
+							    || gf == NULL)
+								{
+									break;
+								}
+							if (!G_IS_FILE_INFO (gfi))
+								{
+									continue;
+								}
+
+							GFileType gft;
+
+							gft = g_file_info_get_file_type (gfi);
+							if (gft == G_FILE_TYPE_DIRECTORY
+							    || gft == G_FILE_TYPE_REGULAR)
+								{
+									g_string_append_printf (ret,
+									                        "<li>%s%s%s</li>\n",
+									                        gft == G_FILE_TYPE_DIRECTORY ? g_strdup_printf ("<a href=\"/zakjukebox/index/cd/%s\">", g_file_get_basename (gf)) : "",
+									                        g_file_get_basename (gf),
+									                        gft == G_FILE_TYPE_DIRECTORY ? "</a>" : "");
+								}
 						}
 				}
 		}
@@ -94,7 +120,8 @@ index_index (GMatchInfo *minfo, gpointer user_data)
 	TmplSymbol *symbol = NULL;
 	gchar *str;
 
-	gchar *dir;
+	g_autofree gchar *pwd;
+	g_autofree gchar *dir;
 
 	Commons *commons = (Commons *)user_data;
 
@@ -113,7 +140,16 @@ index_index (GMatchInfo *minfo, gpointer user_data)
 	tmpl_symbol_assign_string (symbol, "");
 
 	symbol = tmpl_scope_get (scope, "body");
-	dir = render_dir (commons, "/");
+
+	pwd = zak_cgi_session_get_value (commons->zcgi_session, "pwd");
+	if (pwd == NULL
+	    || g_strcmp0 (pwd, "") == 0)
+		{
+			pwd = g_strdup ("");
+			zak_cgi_session_set_value (commons->zcgi_session, "pwd", "");
+		}
+	dir = render_dir (commons, pwd);
+
 	tmpl_symbol_assign_string (symbol, dir);
 
 	symbol = tmpl_scope_get (scope, "body_tag");
@@ -129,3 +165,67 @@ index_index (GMatchInfo *minfo, gpointer user_data)
 
 	g_free (str);
 }
+
+void
+index_cd (GMatchInfo *minfo, gpointer user_data)
+{
+	g_autofree gchar *dir;
+	g_autofree gchar *pwd;
+
+	gboolean up;
+
+	Commons *commons = (Commons *)user_data;
+
+	pwd = zak_cgi_session_get_value (commons->zcgi_session, "pwd");
+	if (pwd == NULL)
+		{
+			pwd = g_strdup ("");
+		}
+
+	dir = g_match_info_fetch_named (minfo, "dir");
+	if (dir == NULL)
+		{
+			dir = g_strdup ("");
+		}
+	else
+		{
+			up = (g_strcmp0 (dir, "{up}") == 0);
+			if (up)
+				{
+					gchar *slash;
+
+					slash = g_strrstr (pwd, "/");
+					if (slash == NULL)
+						{
+							g_free (dir);
+							dir = g_strdup ("");
+						}
+					else
+						{
+							g_autofree gchar *tmp;
+
+							tmp = g_strndup (pwd, slash - pwd);
+							g_free (dir);
+							dir = g_strdup (tmp);
+						}
+				}
+		}
+
+	if (g_strcmp0 (dir, "") == 0)
+		{
+			zak_cgi_session_set_value (commons->zcgi_session, "pwd", "");
+		}
+	else
+		{
+			if (up)
+				{
+					zak_cgi_session_set_value (commons->zcgi_session, "pwd", dir);
+				}
+			else
+				{
+					zak_cgi_session_set_value (commons->zcgi_session, "pwd", g_strdup_printf ("%s%s%s", pwd, g_strcmp0 (pwd, "") != 0 ? "/" : "", dir));
+				}
+		}
+
+	zak_cgi_main_redirect (commons->zcgi_main, "/zakjukebox/index/index");
+}
diff --git a/src/index.h b/src/index.h
index bbf0327..8e532f1 100644
--- a/src/index.h
+++ b/src/index.h
@@ -28,6 +28,7 @@
 
 
 void index_index (GMatchInfo *minfo, gpointer user_data);
+void index_cd (GMatchInfo *minfo, gpointer user_data);
 
 
 #endif /* __INDEX_H__ */
diff --git a/src/main.c b/src/main.c
index fc98002..2cec1dd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -76,6 +76,8 @@ main (int argc, char *argv[])
 	zak_cgi_url_connect (zcgi_url, "/", (ZakCgiUrlConnectedFunction)index_index, commons);
 	zak_cgi_url_connect (zcgi_url, "/index[/]?", (ZakCgiUrlConnectedFunction)index_index, commons);
 	zak_cgi_url_connect (zcgi_url, "/index/index", (ZakCgiUrlConnectedFunction)index_index, commons);
+	zak_cgi_url_connect (zcgi_url, "/index/cd/(?<dir>[.a-zA-Z0-9\\-_]+)", (ZakCgiUrlConnectedFunction)index_cd, commons);
+	zak_cgi_url_connect (zcgi_url, "/index/cd/(?<dir>{up})", (ZakCgiUrlConnectedFunction)index_cd, commons);
 
 	zak_cgi_url_dispatch (zcgi_url);