From 4d55d4ada3ebbdd6b99855fe0767d26490955a22 Mon Sep 17 00:00:00 2001 From: Moritz Wilhelmy Date: Thu, 22 May 2014 08:30:13 +0000 Subject: [PATCH 06/29] add support for (Free)BSD extended attributes enable with `./configure --with-attr` and `mimetype.use-xattr = "enable"` in the config. set attribute with: setextattr user Content-Type text/plain path/to/www/file From: Moritz Wilhelmy git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2966 152afb58-edef-0310-8abb-c4023f1b3aa9 --- NEWS | 1 + configure.ac | 25 +++++++++++++++++-------- src/mod_dirlisting.c | 17 ++++++++++++++--- src/stat_cache.c | 21 +++++++++++++++++++-- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 0bf0313..84a1c80 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ NEWS * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body * fix bad shift in conditional netmask ".../0" handling * add more mime types and a script to generate mime.conf (fixes #2579) + * add support for (Free)BSD extended attributes - 1.4.35 - 2014-03-12 * [network/ssl] fix build error if TLSEXT is disabled diff --git a/configure.ac b/configure.ac index ae35234..48e6b52 100644 --- a/configure.ac +++ b/configure.ac @@ -218,14 +218,23 @@ AC_ARG_WITH(attr, AC_HELP_STRING([--with-attr],[enable extended attribute suppor [WITH_ATTR=$withval],[WITH_ATTR=no]) AC_MSG_RESULT($withval) if test "$WITH_ATTR" != "no"; then - AC_CHECK_LIB(attr, attr_get, [ - AC_CHECK_HEADERS([attr/attributes.h],[ - ATTR_LIB=-lattr - AC_DEFINE([HAVE_XATTR], [1], [libattr]) - AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1]) - ]) - ]) - AC_SUBST(ATTR_LIB) + # libattr (linux only?) + AC_CHECK_LIB(attr, attr_get, [ + AC_CHECK_HEADERS([attr/attributes.h],[ + ATTR_LIB=-lattr + AC_DEFINE([HAVE_XATTR], [1], [libattr]) + AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1]) + ]) + ]) + AC_SUBST(ATTR_LIB) + + # (Free)BSD extattr + AC_CHECK_FUNC([extattr_get_file], [ + AC_CHECK_HEADERS([sys/extattr.h],[ + AC_DEFINE([HAVE_EXTATTR], [1], [BSD extended attributes]) + AC_DEFINE([HAVE_SYS_EXTATTR_H], [1]) + ]) + ]) fi dnl openssl on solaris needs -lsocket -lnsl diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c index cd5809e..6aba403 100644 --- a/src/mod_dirlisting.c +++ b/src/mod_dirlisting.c @@ -31,6 +31,10 @@ #include #endif +#ifdef HAVE_SYS_EXTATTR_H +#include +#endif + #include "version.h" /* plugin config for all request/connections */ @@ -644,7 +648,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf size_t k; const char *content_type; long name_max; -#ifdef HAVE_XATTR +#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR) char attrval[128]; int attrlen; #endif @@ -820,8 +824,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf tmp = files.ent[i]; content_type = NULL; -#ifdef HAVE_XATTR - +#if defined(HAVE_XATTR) if (con->conf.use_xattr) { memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1); attrlen = sizeof(attrval) - 1; @@ -830,6 +833,14 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf content_type = attrval; } } +#elif defined(HAVE_EXTATTR) + if (con->conf.use_xattr) { + memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1); + if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, "Content-Type", attrval, sizeof(attrval)-1))) { + attrval[attrlen] = '\0'; + content_type = attrval; + } + } #endif if (content_type == NULL) { diff --git a/src/stat_cache.c b/src/stat_cache.c index 480aae4..9007325 100644 --- a/src/stat_cache.c +++ b/src/stat_cache.c @@ -18,6 +18,10 @@ # include #endif +#ifdef HAVE_SYS_EXTATTR_H +# include +#endif + #ifdef HAVE_FAM_H # include #endif @@ -210,7 +214,7 @@ void stat_cache_free(stat_cache *sc) { free(sc); } -#ifdef HAVE_XATTR +#if defined(HAVE_XATTR) static int stat_cache_attr_get(buffer *buf, char *name) { int attrlen; int ret; @@ -224,6 +228,19 @@ static int stat_cache_attr_get(buffer *buf, char *name) { } return ret; } +#elif defined(HAVE_EXTATTR) +static int stat_cache_attr_get(buffer *buf, char *name) { + ssize_t attrlen = 1024; + + buffer_prepare_copy(buf, attrlen); + + if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, attrlen-1))) { + buf->used = attrlen + 1; + buf->ptr[attrlen] = '\0'; + return 0; + } + return -1; +} #endif /* the famous DJB hash function for strings */ @@ -592,7 +609,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_ if (S_ISREG(st.st_mode)) { /* determine mimetype */ buffer_reset(sce->content_type); -#ifdef HAVE_XATTR +#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR) if (con->conf.use_xattr) { stat_cache_attr_get(sce->content_type, name->ptr); } -- 2.4.5