diff --git a/src/protocol/Makefile b/src/protocol/Makefile index c4bee0682..7801c97ee 100644 --- a/src/protocol/Makefile +++ b/src/protocol/Makefile @@ -1,8 +1,6 @@ top_builddir=../.. include $(top_builddir)/Makefile.config -SUBDIRS = auth file http - SUBDIRS-$(CONFIG_BITTORRENT) += bittorrent SUBDIRS-$(CONFIG_FINGER) += finger SUBDIRS-$(CONFIG_FSP) += fsp @@ -12,11 +10,10 @@ SUBDIRS-$(CONFIG_NNTP) += nntp SUBDIRS-$(CONFIG_SMB) += smb SUBDIRS-$(CONFIG_URI_REWRITE) += rewrite -OBJS = about.o date.o header.o protocol.o proxy.o uri.o user.o +SUBDIRS = auth file http OBJS-$(CONFIG_DATA) += data.o -OBJS-$(CONFIG_CGI) += common.o -OBJS-$(CONFIG_FSP) += common.o -OBJS-$(CONFIG_SMB) += common.o + +OBJS = about.o common.o date.o header.o protocol.o proxy.o uri.o user.o include $(top_srcdir)/Makefile.lib diff --git a/src/protocol/common.c b/src/protocol/common.c index 2195a9d17..e18930cfc 100644 --- a/src/protocol/common.c +++ b/src/protocol/common.c @@ -17,7 +17,13 @@ #include "elinks.h" +#include "config/options.h" #include "protocol/common.h" +#include "protocol/protocol.h" +#include "protocol/uri.h" +#include "util/conv.h" +#include "util/memory.h" +#include "util/string.h" /* Close all non-terminal file descriptors. */ @@ -35,3 +41,93 @@ close_all_non_term_fd(void) for (n = 3; n < max; n++) close(n); } + +enum connection_state +init_directory_listing(struct string *page, struct uri *uri) +{ + struct string dirpath = NULL_STRING; + struct string location = NULL_STRING; + unsigned char *info; + int local = (uri->protocol == PROTOCOL_FILE); + + if (!init_string(page) + || !init_string(&dirpath) + || !init_string(&location) + || !add_uri_to_string(&dirpath, uri, URI_DATA) + || !add_uri_to_string(&location, uri, URI_DIR_LOCATION)) + goto out_of_memory; + + if (dirpath.length > 0 + && !dir_sep(dirpath.source[dirpath.length - 1]) + && !add_char_to_string(&dirpath, '/')) + goto out_of_memory; + + if (!local && !add_char_to_string(&location, '/')) + goto out_of_memory; + + if (!add_to_string(page, "\n")) + goto out_of_memory; + + if (!local && !add_string_to_string(page, &location)) + goto out_of_memory; + + if (!add_html_to_string(page, dirpath.source, dirpath.length) + || !add_to_string(page, "\n\n\n\n

")) + goto out_of_memory; + + switch (uri->protocol) { + case PROTOCOL_FILE: + info = "Local"; + break; + case PROTOCOL_FTP: + info = "FTP"; + break; + case PROTOCOL_FSP: + info = "FSP"; + break; + default: + info = "?"; + } + + if (!add_to_string(page, info) + || !add_to_string(page, " directory ")) + goto out_of_memory; + + if (!local && !add_string_to_string(page, &location)) + goto out_of_memory; + + /* Make the directory path with links to each subdir. */ + { + unsigned char *slash = dirpath.source; + unsigned char *pslash = slash; + + while ((slash = strchr(slash, '/'))) { + /* FIXME: htmlesc? At least we should escape quotes. --pasky */ + if (!add_to_string(page, "") + || !add_html_to_string(page, pslash, slash - pslash) + || !add_to_string(page, "/")) + goto out_of_memory; + + pslash = ++slash; + } + } + + if (!add_to_string(page, "

\n
")) {
+out_of_memory:
+		done_string(page);
+	}
+
+	done_string(&dirpath);
+	done_string(&location);
+
+	return page->length > 0 ? S_OK : S_OUT_OF_MEM;
+}
diff --git a/src/protocol/common.h b/src/protocol/common.h
index 1f43b7900..116541850 100644
--- a/src/protocol/common.h
+++ b/src/protocol/common.h
@@ -1,7 +1,15 @@
 #ifndef EL__PROTOCOL_COMMON_H
 #define EL__PROTOCOL_COMMON_H
 
+#include "network/state.h"
+
+struct string;
+struct uri;
+
 /* Close all non-terminal file descriptors. */
 void close_all_non_term_fd(void);
 
+enum connection_state
+init_directory_listing(struct string *page, struct uri *uri);
+
 #endif
diff --git a/src/protocol/uri.h b/src/protocol/uri.h
index dac654e58..cb6babb62 100644
--- a/src/protocol/uri.h
+++ b/src/protocol/uri.h
@@ -160,6 +160,9 @@ enum uri_component {
 	/* Used for HTTP CONNECT method info */
 	URI_HTTP_CONNECT	= URI_HOST | URI_PORT | URI_DEFAULT_PORT,
 
+	/* Used for adding directory listing HTML header, */
+	URI_DIR_LOCATION	= URI_PROTOCOL | URI_HOST | URI_PORT | URI_IDN,
+
 	/* Used for getting the host of a DNS query. As a hidden bonus we get
 	 * IPv6 hostnames without the brackets because we don't ask for
 	 * URI_PORT. */