diff options
Diffstat (limited to 'src/mod_dirlisting.c')
-rw-r--r-- | src/mod_dirlisting.c | 92 |
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\">- </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; |