|
|
|
@ -329,12 +329,12 @@ static int buffer_copy_dirname(buffer *dst, buffer *file) {
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_LSTAT |
|
|
|
|
static int stat_cache_lstat(server *srv, char *dname, struct stat *lst) { |
|
|
|
|
if (lstat(dname, lst) == 0) { |
|
|
|
|
static int stat_cache_lstat(server *srv, buffer *dname, struct stat *lst) { |
|
|
|
|
if (lstat(dname->ptr, lst) == 0) { |
|
|
|
|
return S_ISLNK(lst->st_mode) ? 0 : 1; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sss", |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbs", |
|
|
|
|
"lstat failed for:", |
|
|
|
|
dname, strerror(errno)); |
|
|
|
|
}; |
|
|
|
@ -362,6 +362,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|
|
|
|
struct stat st; |
|
|
|
|
size_t k; |
|
|
|
|
int fd; |
|
|
|
|
struct stat lst; |
|
|
|
|
#ifdef DEBUG_STAT_CACHE |
|
|
|
|
size_t i; |
|
|
|
|
#endif |
|
|
|
@ -522,12 +523,11 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|
|
|
|
* and keeping the file open for the rest of the time. But this can |
|
|
|
|
* only be done at network level. |
|
|
|
|
*
|
|
|
|
|
+ * per default it is not a symlink |
|
|
|
|
* per default it is not a symlink |
|
|
|
|
* */ |
|
|
|
|
#ifdef HAVE_LSTAT |
|
|
|
|
sce->is_symlink = 0; |
|
|
|
|
struct stat lst; |
|
|
|
|
if (stat_cache_lstat(srv, name->ptr, &lst) == 0) { |
|
|
|
|
if (stat_cache_lstat(srv, name, &lst) == 0) { |
|
|
|
|
#ifdef DEBUG_STAT_CACHE |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb", |
|
|
|
|
"found symlink", name); |
|
|
|
@ -540,31 +540,34 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|
|
|
|
* skip the symlink stuff if our path is / |
|
|
|
|
**/ |
|
|
|
|
else if ((name->used > 2)) { |
|
|
|
|
char *dname, *s_cur; |
|
|
|
|
buffer *dname; |
|
|
|
|
char *s_cur; |
|
|
|
|
|
|
|
|
|
dname = buffer_init(); |
|
|
|
|
buffer_copy_string_buffer(dname, name); |
|
|
|
|
|
|
|
|
|
dname = strndup(name->ptr, name->used); |
|
|
|
|
while ((s_cur = strrchr(dname,'/'))) { |
|
|
|
|
while ((s_cur = strrchr(dname->ptr,'/'))) { |
|
|
|
|
*s_cur = '\0'; |
|
|
|
|
if (dname == s_cur) { |
|
|
|
|
if (dname->ptr == s_cur) { |
|
|
|
|
#ifdef DEBUG_STAT_CACHE |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "reached /"); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG_STAT_CACHE |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sss", |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbs", |
|
|
|
|
"checking if", dname, "is a symlink"); |
|
|
|
|
#endif |
|
|
|
|
if (stat_cache_lstat(srv, dname, &lst) == 0) { |
|
|
|
|
sce->is_symlink = 1; |
|
|
|
|
#ifdef DEBUG_STAT_CACHE |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "ss", |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb", |
|
|
|
|
"found symlink", dname); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
free(dname); |
|
|
|
|
buffer_free(dname); |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|