summaryrefslogtreecommitdiff
path: root/src/mod_dirlisting.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_dirlisting.c')
-rw-r--r--src/mod_dirlisting.c92
1 files changed, 77 insertions, 15 deletions
diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
index 9b06fdb..69eb1e9 100644
--- a/src/mod_dirlisting.c
+++ b/src/mod_dirlisting.c
@@ -51,6 +51,9 @@ typedef struct {
unsigned short dir_listing;
unsigned short hide_dot_files;
unsigned short show_readme;
+ unsigned short hide_readme_file;
+ unsigned short show_header;
+ unsigned short hide_header_file;
excludes_buffer *excludes;
@@ -62,6 +65,7 @@ typedef struct {
PLUGIN_DATA;
buffer *tmp_buf;
+ buffer *content_charset;
plugin_config **config_storage;
@@ -144,7 +148,9 @@ INIT_FUNC(mod_dirlisting_init) {
plugin_data *p;
p = calloc(1, sizeof(*p));
+
p->tmp_buf = buffer_init();
+ p->content_charset = buffer_init();
return p;
}
@@ -174,6 +180,7 @@ FREE_FUNC(mod_dirlisting_free) {
}
buffer_free(p->tmp_buf);
+ buffer_free(p->content_charset);
free(p);
@@ -228,13 +235,16 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
size_t i = 0;
config_values_t cv[] = {
- { "dir-listing.exclude", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
- { "dir-listing.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
- { "dir-listing.hide-dotfiles", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
- { "dir-listing.external-css", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
- { "dir-listing.encoding", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
- { "dir-listing.show-readme", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
- { "server.dir-listing", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
+ { "dir-listing.exclude", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "dir-listing.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { "dir-listing.hide-dotfiles", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
+ { "dir-listing.external-css", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
+ { "dir-listing.encoding", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
+ { "dir-listing.show-readme", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
+ { "dir-listing.hide-readme-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
+ { "dir-listing.show-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
+ { "dir-listing.hide-header-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
+ { "server.dir-listing", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -253,6 +263,9 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
s->external_css = buffer_init();
s->hide_dot_files = 0;
s->show_readme = 0;
+ s->hide_readme_file = 0;
+ s->show_header = 0;
+ s->hide_header_file = 0;
s->encoding = buffer_init();
cv[0].destination = s->excludes;
@@ -261,7 +274,10 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
cv[3].destination = s->external_css;
cv[4].destination = s->encoding;
cv[5].destination = &(s->show_readme);
- cv[6].destination = &(s->dir_listing); /* old name */
+ cv[6].destination = &(s->hide_readme_file);
+ cv[7].destination = &(s->show_header);
+ cv[8].destination = &(s->hide_header_file);
+ cv[9].destination = &(s->dir_listing); /* old name */
p->config_storage[i] = s;
ca = ((data_config *)srv->config_context->data[i])->value;
@@ -287,6 +303,9 @@ static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_
PATCH(hide_dot_files);
PATCH(encoding);
PATCH(show_readme);
+ PATCH(hide_readme_file);
+ PATCH(show_header);
+ PATCH(hide_header_file);
PATCH(excludes);
/* skip the first, the global context */
@@ -312,6 +331,12 @@ static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_
PATCH(encoding);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) {
PATCH(show_readme);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) {
+ PATCH(hide_readme_file);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) {
+ PATCH(show_header);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) {
+ PATCH(hide_header_file);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) {
PATCH(excludes);
}
@@ -414,7 +439,7 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
"<head>\n"
"<title>Index of "
);
- buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_HTML);
+ buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
BUFFER_APPEND_STRING_CONST(out, "</title>\n");
if (p->conf.external_css->used > 1) {
@@ -461,8 +486,27 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
);
}
- BUFFER_APPEND_STRING_CONST(out, "</head>\n<body>\n<h2>Index of ");
- buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_HTML);
+ BUFFER_APPEND_STRING_CONST(out, "</head>\n<body>\n");
+
+ /* HEADER.txt */
+ if (p->conf.show_header) {
+ stream s;
+ /* if we have a HEADER file, display it in <pre class="header"></pre> */
+
+ buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
+ BUFFER_APPEND_SLASH(p->tmp_buf);
+ BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
+
+ if (-1 != stream_open(&s, p->tmp_buf)) {
+ BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">");
+ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+ BUFFER_APPEND_STRING_CONST(out, "</pre>");
+ }
+ stream_close(&s);
+ }
+
+ BUFFER_APPEND_STRING_CONST(out, "<h2>Index of ");
+ buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
BUFFER_APPEND_STRING_CONST(out,
"</h2>\n"
"<div class=\"list\">\n"
@@ -504,7 +548,7 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
if (-1 != stream_open(&s, p->tmp_buf)) {
BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
- buffer_append_string_encoded(out, s.start, s.size, ENCODING_HTML);
+ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
BUFFER_APPEND_STRING_CONST(out, "</pre>");
}
stream_close(&s);
@@ -602,6 +646,15 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
continue;
}
+ if (p->conf.hide_readme_file) {
+ if (strcmp(dent->d_name, "README.txt") == 0)
+ continue;
+ }
+ if (p->conf.hide_header_file) {
+ if (strcmp(dent->d_name, "HEADER.txt") == 0)
+ continue;
+ }
+
/* compare d_name against excludes array
* elements, skipping any that match.
*/
@@ -691,7 +744,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
BUFFER_APPEND_STRING_CONST(out, "/\">");
- buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_HTML);
+ buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
BUFFER_APPEND_STRING_CONST(out, "</a>/</td><td class=\"m\">");
buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n");
@@ -747,7 +800,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
BUFFER_APPEND_STRING_CONST(out, "\">");
- buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_HTML);
+ buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
BUFFER_APPEND_STRING_CONST(out, "</a></td><td class=\"m\">");
buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">");
@@ -764,7 +817,16 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
free(path);
http_list_directory_footer(srv, con, p, out);
- response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+
+ /* Insert possible charset to Content-Type */
+ if (buffer_is_empty(p->conf.encoding)) {
+ response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+ } else {
+ buffer_copy_string(p->content_charset, "text/html; charset=");
+ buffer_append_string_buffer(p->content_charset, p->conf.encoding);
+ response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
+ }
+
con->file_finished = 1;
return 0;