[mod_dirlisting] place vars closer to where used
allocate memory for PATH_MAX to avoid pathconf() for _PC_NAME_MAXpersonal/stbuehler/tests-path
parent
2f303d8205
commit
dfe471b77c
|
@ -813,45 +813,24 @@ static void http_list_directory_footer(const request_st * const r, plugin_data *
|
|||
}
|
||||
|
||||
static int http_list_directory(request_st * const r, plugin_data * const p, buffer * const dir) {
|
||||
DIR *dp;
|
||||
buffer *out;
|
||||
struct dirent *dent;
|
||||
struct stat st;
|
||||
char *path, *path_file;
|
||||
size_t i;
|
||||
int hide_dotfiles = p->conf.hide_dot_files;
|
||||
dirls_list_t dirs, files, *list;
|
||||
dirls_entry_t *tmp;
|
||||
char sizebuf[sizeof("999.9K")];
|
||||
const buffer *content_type;
|
||||
long name_max;
|
||||
log_error_st * const errh = r->conf.errh;
|
||||
struct tm tm;
|
||||
|
||||
if (buffer_string_is_empty(dir)) return -1;
|
||||
|
||||
i = buffer_string_length(dir);
|
||||
|
||||
#ifdef HAVE_PATHCONF
|
||||
if (0 >= (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
|
||||
/* some broken fs (fuse) return 0 instead of -1 */
|
||||
#ifdef NAME_MAX
|
||||
name_max = NAME_MAX;
|
||||
const uint32_t dlen = buffer_string_length(dir);
|
||||
#if defined __WIN32
|
||||
const uint32_t name_max = FILENAME_MAX;
|
||||
#else
|
||||
name_max = 255; /* stupid default */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
}
|
||||
#elif defined __WIN32
|
||||
name_max = FILENAME_MAX;
|
||||
#else
|
||||
name_max = NAME_MAX;
|
||||
/* allocate based on PATH_MAX rather than pathconf() to get _PC_NAME_MAX */
|
||||
const uint32_t name_max = PATH_MAX - dlen - 1;
|
||||
#endif
|
||||
|
||||
path = malloc(i + name_max + 1);
|
||||
char * const path = malloc(dlen + name_max + 1);
|
||||
force_assert(NULL != path);
|
||||
memcpy(path, dir->ptr, i+1);
|
||||
path_file = path + i;
|
||||
memcpy(path, dir->ptr, dlen+1);
|
||||
char *path_file = path + dlen;
|
||||
log_error_st * const errh = r->conf.errh;
|
||||
|
||||
DIR *dp;
|
||||
struct dirent *dent;
|
||||
if (NULL == (dp = opendir(path))) {
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"opendir failed: %s", dir->ptr);
|
||||
|
@ -860,6 +839,7 @@ static int http_list_directory(request_st * const r, plugin_data * const p, buff
|
|||
return -1;
|
||||
}
|
||||
|
||||
dirls_list_t dirs, files;
|
||||
dirs.ent = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
|
||||
force_assert(dirs.ent);
|
||||
dirs.size = DIRLIST_BLOB_SIZE;
|
||||
|
@ -869,60 +849,58 @@ static int http_list_directory(request_st * const r, plugin_data * const p, buff
|
|||
files.size = DIRLIST_BLOB_SIZE;
|
||||
files.used = 0;
|
||||
|
||||
const int hide_dotfiles = p->conf.hide_dot_files;
|
||||
struct stat st;
|
||||
while ((dent = readdir(dp)) != NULL) {
|
||||
if (dent->d_name[0] == '.') {
|
||||
const char * const d_name = dent->d_name;
|
||||
if (d_name[0] == '.') {
|
||||
if (hide_dotfiles)
|
||||
continue;
|
||||
if (dent->d_name[1] == '\0')
|
||||
if (d_name[1] == '\0')
|
||||
continue;
|
||||
if (dent->d_name[1] == '.' && dent->d_name[2] == '\0')
|
||||
if (d_name[1] == '.' && d_name[2] == '\0')
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->conf.hide_readme_file && !buffer_string_is_empty(p->conf.show_readme)) {
|
||||
if (strcmp(dent->d_name, p->conf.show_readme->ptr) == 0)
|
||||
if (strcmp(d_name, p->conf.show_readme->ptr) == 0)
|
||||
continue;
|
||||
}
|
||||
if (p->conf.hide_header_file && !buffer_string_is_empty(p->conf.show_header)) {
|
||||
if (strcmp(dent->d_name, p->conf.show_header->ptr) == 0)
|
||||
if (strcmp(d_name, p->conf.show_header->ptr) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
i = strlen(dent->d_name);
|
||||
const uint32_t dsz = (uint32_t)strlen(d_name);
|
||||
|
||||
/* compare d_name against excludes array
|
||||
* elements, skipping any that match.
|
||||
*/
|
||||
if (p->conf.excludes
|
||||
&& mod_dirlisting_exclude(errh, p->conf.excludes, dent->d_name, i))
|
||||
&& mod_dirlisting_exclude(errh, p->conf.excludes, d_name, dsz))
|
||||
continue;
|
||||
|
||||
/* NOTE: the manual says, d_name is never more than NAME_MAX
|
||||
* so this should actually not be a buffer-overflow-risk
|
||||
*/
|
||||
if (i > (size_t)name_max) continue;
|
||||
if (dsz > name_max) continue;
|
||||
|
||||
memcpy(path_file, dent->d_name, i + 1);
|
||||
memcpy(path_file, d_name, dsz + 1);
|
||||
if (stat(path, &st) != 0)
|
||||
continue;
|
||||
|
||||
list = &files;
|
||||
if (S_ISDIR(st.st_mode))
|
||||
list = &dirs;
|
||||
|
||||
dirls_list_t * const list = !S_ISDIR(st.st_mode) ? &files : &dirs;
|
||||
if (list->used == list->size) {
|
||||
list->size += DIRLIST_BLOB_SIZE;
|
||||
list->ent = (dirls_entry_t**) realloc(list->ent, sizeof(dirls_entry_t*) * list->size);
|
||||
force_assert(list->ent);
|
||||
}
|
||||
|
||||
tmp = (dirls_entry_t*) malloc(sizeof(dirls_entry_t) + 1 + i);
|
||||
dirls_entry_t * const tmp = list->ent[list->used++] =
|
||||
(dirls_entry_t*) malloc(sizeof(dirls_entry_t) + 1 + dsz);
|
||||
tmp->mtime = st.st_mtime;
|
||||
tmp->size = st.st_size;
|
||||
tmp->namelen = (uint32_t)i;
|
||||
memcpy(DIRLIST_ENT_NAME(tmp), dent->d_name, i + 1);
|
||||
|
||||
list->ent[list->used++] = tmp;
|
||||
tmp->namelen = dsz;
|
||||
memcpy(DIRLIST_ENT_NAME(tmp), d_name, dsz + 1);
|
||||
}
|
||||
closedir(dp);
|
||||
|
||||
|
@ -930,12 +908,15 @@ static int http_list_directory(request_st * const r, plugin_data * const p, buff
|
|||
|
||||
if (files.used) http_dirls_sort(files.ent, files.used);
|
||||
|
||||
out = chunkqueue_append_buffer_open(&r->write_queue);
|
||||
char sizebuf[sizeof("999.9K")];
|
||||
struct tm tm;
|
||||
|
||||
buffer * const out = chunkqueue_append_buffer_open(&r->write_queue);
|
||||
http_list_directory_header(r, p, out);
|
||||
|
||||
/* directories */
|
||||
for (i = 0; i < dirs.used; i++) {
|
||||
tmp = dirs.ent[i];
|
||||
for (uint32_t i = 0; i < dirs.used; ++i) {
|
||||
dirls_entry_t * const tmp = dirs.ent[i];
|
||||
|
||||
buffer_append_string_len(out, CONST_STR_LEN("<tr class=\"d\"><td class=\"n\"><a href=\""));
|
||||
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
|
||||
|
@ -950,9 +931,9 @@ static int http_list_directory(request_st * const r, plugin_data * const p, buff
|
|||
|
||||
/* files */
|
||||
const array * const mimetypes = r->conf.mimetypes;
|
||||
for (i = 0; i < files.used; i++) {
|
||||
tmp = files.ent[i];
|
||||
|
||||
for (uint32_t i = 0; i < files.used; ++i) {
|
||||
dirls_entry_t * const tmp = files.ent[i];
|
||||
const buffer *content_type;
|
||||
#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR) /*(pass full path)*/
|
||||
content_type = NULL;
|
||||
if (r->conf.use_xattr) {
|
||||
|
@ -1016,7 +997,7 @@ URIHANDLER_FUNC(mod_dirlisting_subrequest) {
|
|||
if (buffer_string_is_empty(&r->uri.path)) return HANDLER_GO_ON;
|
||||
if (r->uri.path.ptr[buffer_string_length(&r->uri.path) - 1] != '/') return HANDLER_GO_ON;
|
||||
if (!http_method_get_or_head(r->http_method)) return HANDLER_GO_ON;
|
||||
if (buffer_is_empty(&r->physical.path)) return HANDLER_GO_ON;
|
||||
if (buffer_string_is_empty(&r->physical.path)) return HANDLER_GO_ON;
|
||||
|
||||
mod_dirlisting_patch_config(r, p);
|
||||
|
||||
|
|
Loading…
Reference in New Issue