--- /dev/null
+#
+# Copyright (C) 2008-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=radicale
+PKG_VERSION:=0.10
+PKG_RELEASE:=1
+PKG_MAINTAINER:=Christian Schoenebeck <chris5560@web.de>
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE:=Radicale-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://pypi.python.org/packages/source/R/Radicale/
+PKG_MD5SUM:=32655d8893962956ead0ad690cca6044
+
+# needed for "r"adicale <-> "R"adicale
+PKG_BUILD_DIR:=$(BUILD_DIR)/Radicale-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+# no default dependencies
+PKG_DEFAULT_DEPENDS=
+
+define Package/$(PKG_NAME)/Default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Web Servers/Proxies
+ URL:=http://radicale.org/
+ PKGARCH:=all
+ USERID:=radicale=5232:radicale=5232
+endef
+define Package/$(PKG_NAME)-py2
+ $(call Package/$(PKG_NAME)/Default)
+ PYTHON_VERSION:=2.7
+ TITLE:=Radicale CalDAV/CardDAV server (Python 2)
+ VARIANT:=python2
+ DEPENDS:=+python-logging +python-openssl +python-xml +python-codecs
+endef
+define Package/$(PKG_NAME)-py3
+ $(call Package/$(PKG_NAME)/Default)
+ PYTHON_VERSION:=3.4
+ TITLE:=Radicale CalDAV/CardDAV server (Python 3)
+ VARIANT:=python3
+ DEPENDS:=+python3-logging +python3-openssl +python3-xml +python3-codecs +python3-email @BROKEN
+endef
+
+# shown in LuCI package description
+define Package/$(PKG_NAME)-py2/description
+Radicale CalDAV/CardDAV server (Python 2) - Homepage: http://radicale.org/
+endef
+define Package/$(PKG_NAME)-py3/description
+Radicale CalDAV/CardDAV server (Python 3) - Homepage: http://radicale.org/
+endef
+
+# shown in make menuconfig <Help>
+define Package/$(PKG_NAME)-py2/config
+ help
+ The Radicale Project is a CalDAV (calendar) and CardDAV (contact) server.
+ It aims to be a light solution, easy to use, easy to install, easy to configure.
+ As a consequence, it requires few software dependances and is pre-configured to work out-of-the-box.
+ !!! Will install and use Python $(PYTHON_VERSION) !!!
+ .
+ Version : $(PKG_VERSION)
+ Homepage: http://radicale.org/
+ .
+ $(PKG_MAINTAINER)
+endef
+Package/$(PKG_NAME)-py3/config = $(Package/$(PKG_NAME)-py2/config)
+
+define Package/$(PKG_NAME)-py2/conffiles
+/etc/config/radicale
+/etc/radicale/users
+/etc/radicale/rights
+endef
+Package/$(PKG_NAME)-py3/conffiles = $(Package/$(PKG_NAME)-py2/conffiles)
+
+define Build/Configure
+endef
+define Build/Compile
+endef
+
+define Package/$(PKG_NAME)-py2/preinst
+ #!/bin/sh
+ [ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit
+
+ # stop service if PKG_UPGRADE
+ [ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/$(PKG_NAME) stop >/dev/null 2>&1
+
+ exit 0 # supress errors from stop command
+endef
+define Package/$(PKG_NAME)-py3/preinst
+$(call Package/$(PKG_NAME)-py2/preinst)
+endef
+
+define Package/$(PKG_NAME)-py2/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/radicale.init $(1)/etc/init.d/radicale
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_BIN) ./files/radicale.hotplug $(1)/etc/hotplug.d/iface/80-radicale
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/radicale.config $(1)/etc/config/radicale
+
+ $(INSTALL_DIR) $(1)/etc/radicale/ssl
+ $(INSTALL_DATA) ./files/config.template $(1)/etc/radicale/
+ $(INSTALL_DATA) ./files/logging.template $(1)/etc/radicale/
+ $(INSTALL_DATA) ./files/radicale.users $(1)/etc/radicale/users
+ $(INSTALL_DATA) ./files/radicale.rights $(1)/etc/radicale/rights
+
+ $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale
+ $(CP) \
+ $(PKG_BUILD_DIR)/radicale/* \
+ $(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale
+
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/radicale $(1)/usr/bin/
+endef
+define Package/$(PKG_NAME)-py3/install
+ $(call Package/$(PKG_NAME)-py2/install, $(1))
+endef
+
+define Package/$(PKG_NAME)-py2/postinst
+ #!/bin/sh
+ # patch /usr/bin/radicale force run using python2
+ /bin/sed -i 's/python/python2/' $${IPKG_INSTROOT}/usr/bin/radicale
+endef
+define Package/$(PKG_NAME)-py3/postinst
+ #!/bin/sh
+ # patch /usr/bin/radicale force run using python3
+ /bin/sed -i 's/python/python3/' $${IPKG_INSTROOT}/usr/bin/radicale
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)-py2))
+$(eval $(call BuildPackage,$(PKG_NAME)-py3))
--- /dev/null
+# -*- mode: conf -*-
+# vim:ft=cfg
+
+### AUTO-GENERATED CONFIGURATION
+### USED BY RADICALE
+### DO NOT EDIT
+### SEE /etc/config/radicale INSTEAD
+
+[server]
+# daemon # handled by /etc/init.d/radicale
+# pid # handled by /etc/init.d/radicale
+
+[encoding]
+
+[well-known]
+
+[auth]
+# htpasswd_filename # hard-coded /etc/radicale/users
+
+[git]
+
+[rights]
+# file # hard-coded /etc/radicale/rights
+
+[storage]
+
+[logging]
+# config # hard-coded /var/etc/radicale/logging
+
+[headers]
--- /dev/null
+# -*- mode: conf -*-
+# vim:ft=cfg
+
+### AUTO-GENERATED CONFIGURATION
+### USED BY RADICALE
+### DO NOT EDIT
+### SEE /etc/config/radicale INSTEAD
+
+[loggers]
+keys = root
+
+[handlers]
+keys = console,file,syslog
+
+[formatters]
+keys = simple,full,syslog
+
+[logger_root]
+level = DEBUG
+handlers = console,file,syslog
+
+[handler_console]
+class = StreamHandler
+args = (sys.stdout,)
+formatter = simple
+# level = WARNING # set via /etc/config/radicale
+
+[handler_file]
+class = handlers.RotatingFileHandler
+formatter = full
+# level = INFO # set via /etc/config/radicale
+# args = ('[filename]','a',[maxbytes],[backupcount]) # set via /etc/config/radicale
+
+[handler_syslog]
+class = handlers.SysLogHandler
+args = ('/dev/log', handlers.SysLogHandler.LOG_DAEMON)
+formatter = syslog
+# level = WARNING # set via /etc/config/radicale
+
+[formatter_simple]
+format = %(message)s
+
+[formatter_full]
+format = %(asctime)s - %(levelname)s: %(message)s
+
+[formatter_syslog]
+format = radicale [%(process)d]: %(message)s
--- /dev/null
+#
+# You find additional information on Radicale Homepage
+# http://radicale.org
+#
+# OpenWrt's wiki needs to be setup/updated ;-)
+#
+# if setting additional options please remember that UCI does not support
+# section names and option names with "-" (Dash) inside their name
+# to use them anyway replace "-" with "_" (Underscore)
+# Each Radicale's config [section] is setup as UCI config setting 'section'
+#
+
+####################################################
+# Server options
+#
+config setting 'server'
+
+ # hostname:port
+ # IPv4 syntax: address:port
+ # IPv6 syntax: [address]:port
+ # ATTENTION:
+ # only use ports > 1024 (non-privileged Ports)
+ # because this implementation is running as non-root user
+ # Default: 0.0.0.0:5232
+# list hosts '0.0.0.0:5232'
+# list hosts 'localhost:5232'
+
+ # SSL flag, enable HTTPS protocol
+ # Default: 0 (disabled)
+# option ssl '1'
+
+ # SSL Protocol used. See python's ssl module for available values
+ # Default: PROTOCOL_SSLv23
+# option protocol 'PROTOCOL_SSLv23'
+
+ # Ciphers available. See python's ssl module for available ciphers
+# option ciphers ''
+
+ # SSL certificate path and file
+# option certificate '/etc/radicale/ssl/server.crt'
+
+ # SSL private key path and file
+# option key '/etc/radicale/ssl/server.key'
+
+ # Reverse DNS to resolve client address in logs
+ # Default: 0 (disabled)
+# option dns_lookup '1'
+
+ # Message displayed in the client when a password is needed
+# option realm 'Radicale - Password Required'
+
+
+####################################################
+# Encoding options
+#
+config setting 'encoding'
+
+ # Encoding for responding requests
+# option request 'utf-8'
+
+ # Encoding for storing local collections
+# option stock 'utf-8'
+
+
+####################################################
+# Authentication options
+#
+config setting 'auth'
+
+ # Authentication method
+ # Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom
+ # Default: None
+ # if setting 'htpasswd' the file /etc/radicale/users is used (hardcoded)
+# option type 'htpasswd'
+
+ # Htpasswd encryption method
+ # Value: plain | sha1 | ssha | crypt
+# option htpasswd_encryption 'crypt'
+
+ # for other authenication methods consult Radicale documentation
+ # and set options here
+
+
+####################################################
+# Git default options
+#
+config setting 'git'
+
+ # Git default options
+# option committer 'Radicale <radicale@example.com>'
+
+
+####################################################
+# Rights backend
+#
+config setting 'rights'
+
+ # Value: None | authenticated | owner_only | owner_write | from_file | custom
+ # Default: None
+ # if setting 'from_file' the file /etc/radicale/rights is used (hardcoded)
+# option type 'from_file'
+
+ # Custom rights handler
+# option custom_handler ''
+
+
+####################################################
+# Storage backend
+# -------
+# WARNING: ONLY "filesystem" IS DOCUMENTED AND TESTED,
+# OTHER BACKENDS ARE NOT READY FOR PRODUCTION.
+# -------
+#
+config setting 'storage'
+ # Value: filesystem | multifilesystem | database | custom
+ option type 'filesystem'
+ option filesystem_folder '/srv/radicale'
+
+
+####################################################
+# Additional HTTP headers
+#
+config setting 'headers'
+ # enable all if using CardDavMATE-, CalDavZAP- or InfCloud- WEBclient
+# list Access_Control_Allow_Origin '*'
+# list Access_Control_Allow_Methods 'GET'
+# list Access_Control_Allow_Methods 'POST'
+# list Access_Control_Allow_Methods 'OPTIONS'
+# list Access_Control_Allow_Methods 'PROPFIND'
+# list Access_Control_Allow_Methods 'PROPPATCH'
+# list Access_Control_Allow_Methods 'REPORT'
+# list Access_Control_Allow_Methods 'PUT'
+# list Access_Control_Allow_Methods 'MOVE'
+# list Access_Control_Allow_Methods 'DELETE'
+# list Access_Control_Allow_Methods 'LOCK'
+# list Access_Control_Allow_Methods 'UNLOCK'
+# list Access_Control_Allow_Headers 'User-Agent'
+# list Access_Control_Allow_Headers 'Authorization'
+# list Access_Control_Allow_Headers 'Content-type'
+# list Access_Control_Allow_Headers 'Depth'
+# list Access_Control_Allow_Headers 'If-match'
+# list Access_Control_Allow_Headers 'If-None-Match'
+# list Access_Control_Allow_Headers 'Lock-Token'
+# list Access_Control_Allow_Headers 'Timeout'
+# list Access_Control_Allow_Headers 'Destination'
+# list Access_Control_Allow_Headers 'Overwrite'
+# list Access_Control_Allow_Headers 'X-client'
+# list Access_Control_Allow_Headers 'X-Requested-With'
+# list Access_Control_Expose_Headers 'Etag'
+
+
+####################################################
+# Global logging options
+#
+config setting 'logging'
+
+ # Set the default logging level to debug for all outputs (ignore output level settings)
+ # Default: 0 (disabled)
+# option debug '1'
+ # Log all environment variables (including those set in the shell) when starting
+ # Default: 0 (disabled)
+# option full_environment '1'
+
+
+####################################################
+# Spezial logging options
+# !!! not documented in Radicale documentation
+# !!! special settings for this implementation
+#
+config logging 'logger'
+
+ # Level: DEBUG | INFO | WARNING | ERROR | CRITICAL
+ # To nearly disable logging set level to critical
+
+ # log level on console
+# option console_level 'ERROR'
+
+ # Here we use Rotating Logfiles in this implementation
+ # !!! if maxbytes and/or backupcount is set to 0 !!!
+ # !!! file rotation is disabled and logfile grows endless !!!
+ # log level
+# option file_level 'INFO'
+ # directory where log files are written
+# option file_path '/var/log/radicale'
+ # max size of each logfile (see warning above)
+# option file_maxbytes '8196'
+ # number of backup files to create (see warning above)
+# option file_backupcount '1'
+
+ # log level for syslog logging
+# option syslog_level 'WARNING'
+
--- /dev/null
+#!/bin/sh
+
+# only (re-)start on ifup
+[ "$ACTION" = "ifup" ] || exit 0
+
+_PID=$(ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}')
+kill -1 $_PID 2>/dev/null
+if [ $? -eq 0 ]; then
+ # only restart if already running
+ logger -p user.info -t "radicale[$_PID]" \
+ "Restart request due to '$ACTION' of interface '$INTERFACE'"
+ /etc/init.d/radicale restart
+else
+ # only start if enabled
+ /etc/init.d/radicale enabled && /etc/init.d/radicale start
+fi
--- /dev/null
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2015 OpenWrt.org
+
+START=80
+STOP=10
+
+CFGDIR=/var/etc/radicale
+SYSCFG=$CFGDIR/config
+LOGCFG=$CFGDIR/logging
+
+DATADIR="/srv/radicale"
+LOGDIR=""
+
+PGREP="ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}' "
+
+# we could start with empty configuration file using defaults
+[ -f /etc/config/radicale ] || touch /etc/config/radicale
+
+_uci2radicale() {
+ local _SYSTMP="$SYSCFG.tmp"
+ local _LOGTMP="$LOGCFG.tmp"
+ local _LOPT # list option name
+ local _LVAL # list option value
+ local _STYPE # section type
+ local _SNAME # section name
+ local _console_level="ERROR" # logging console level
+ local _file_level="INFO" # logging file level
+ local _file_path="/var/log/radicale" # logging file path
+ local _file_maxbytes="8196" # logging file maxBytes
+ local _file_backupcount="1" # logging file backupCount
+ local _syslog_level="WARNING" # logging syslog level
+
+ # write list values to config
+ _write_list() {
+ _write_value "$_LOPT" "$_LVAL" # there might be spaces in _LVAL
+ _LOPT=""
+ _LVAL=""
+ }
+
+ _write_value() {
+ # $1 option
+ # $2 value
+ local __OPT=$1
+ local __VAL=$2
+ # section "server" ignore option "daemon" and "pid"
+ [ "$_SNAME" = "server" -a "$__OPT" = "daemon" ] && return 0
+ [ "$_SNAME" = "server" -a "$__OPT" = "pid" ] && return 0
+ # section "logging" ignore option "config" (logging config file)
+ [ "$_SNAME" = "logging" -a "$__OPT" = "config" ] && return 0
+ # section "auth" ignore option "htpasswd_filename" (htpasswd file)
+ [ "$_SNAME" = "auth" -a "$__OPT" = "htpasswd_filename" ] && return 0
+ # section "rights" ignore option "file" (reg-based rights file)
+ [ "$_SNAME" = "rights" -a "$__OPT" = "file" ] && return 0
+ # section "headers" replace "_" with "-" in option (UCI problem)
+ [ "$_SNAME" = "headers" ] && __OPT=$(echo "$__OPT" | sed -e "s#_#-#g")
+ # save data driectory
+ [ "$_SNAME" = "storage" -a "$__OPT" = "filesystem_folder" ] && DATADIR="$__VAL"
+ # special handling for well-known, value needs single quotes
+ [ "$_SNAME" = "well-known" -a "${__VAL#*\%\(}" != "$__VAL" ] && __VAL="'$__VAL'"
+ # handling of log settings
+ if [ "$_STYPE" = "logging" -a "$_SNAME" = "logger" ]; then
+ eval "_$__OPT='$__VAL'" # set to environment for later use
+ else
+ # handle bool
+ [ "$__VAL" = "0" ] && __VAL="False"
+ [ "$__VAL" = "1" ] && __VAL="True"
+ # append data to the corresponding section
+ sed -i "/\[$_SNAME\]/a $__OPT = $__VAL" $_SYSTMP
+ fi
+ }
+
+ # redefined callback for sections when calling config_load
+ config_cb() {
+ # $1 "Type"
+ # $2 "Name"
+ # write out last list option
+ [ -n "$_LOPT" ] && _write_list
+ # mark invalid
+ _STYPE=""
+ _SNAME=""
+ # check section type
+ [ "$1" = "setting" -o "$1" = "logging" ] && {
+ _STYPE="$1"
+ _SNAME="$2"
+ }
+ # translate section name
+ [ "$2" = "well_known" ] && _SNAME="well-known"
+ return 0
+ }
+
+ # redefined callback for lists when calling config_load
+ list_cb() {
+ # $1 name of variable
+ # $2 value
+ # invalid section type then ignore
+ [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
+ # write out last list option if new list starts
+ [ -n "$_LOPT" -a "$_LOPT" != "$1" ] && _write_list
+ # new list option
+ if [ -z "$_LOPT" ]; then
+ _LOPT="$1"
+ _LVAL="$2"
+ else
+ _LVAL="$_LVAL, $2"
+ fi
+ return 0
+ }
+
+ # redefined callback for options when calling config_load
+ option_cb() {
+ # $1 name of variable
+ # $2 value
+ local __OPT="$1"
+ local __VAL="$2"
+ # invalid section type then ignore
+ [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
+ # ignore list entrys will be handled by list_cb()
+ [ "${__OPT#*_ITEM}" != "$__OPT" ] && return 0 # ignore lists *_ITEM*
+ [ "${__OPT#*_LENGTH}" != "$__OPT" ] && return 0 # ignore lists *_LENGTH
+ # write out last list option and clear
+ [ -n "$_LOPT" ] && _write_list
+ # write to file
+ _write_value "$__OPT" "$__VAL" # there might be spaces in __VAL
+ return 0
+ }
+
+ # temporary config file
+ # radicale need read access
+ mkdir -m0755 -p $CFGDIR
+
+ cp /etc/radicale/config.template $_SYSTMP
+ config_load radicale # calling above config_cb()/option_cb()/list_cb() and write into $_SYSTMP
+ sed -i "/\[logging\]/a config = /var/etc/radicale/logging" $_SYSTMP # hard-code logging config
+ sed -i "/\[auth\]/a htpasswd_filename = /etc/radicale/users" $_SYSTMP # hard-code htpasswd
+ sed -i "/\[rights\]/a file = /etc/radicale/rights" $_SYSTMP # hard-code regexp-based rights
+
+ # temporary logging config file
+ cp /etc/radicale/logging.template $_LOGTMP
+ LOGDIR="$_file_path"
+ sed -i "/\[handler_console\]/a level = $_console_level" $_LOGTMP
+ sed -i "/\[handler_file\]/a level = $_file_level" $_LOGTMP
+ sed -i "/\[handler_file\]/a args = ('$_file_path/radicale','a',$_file_maxbytes,$_file_backupcount)" $_LOGTMP
+ sed -i "/\[handler_syslog\]/a level = $_syslog_level" $_LOGTMP
+
+ # move tmp to final
+ mv -f $_SYSTMP $SYSCFG
+ mv -f $_LOGTMP $LOGCFG
+}
+
+_set_permission() {
+ # config file permissions (read access for group)
+ chmod 644 $SYSCFG $LOGCFG
+ chgrp -R radicale $CFGDIR
+ # log directory (full access and owner)
+ [ -d $LOGDIR ] || mkdir -m0755 -p $LOGDIR
+ chown -R radicale:radicale $LOGDIR
+ # data directory does not exist
+ [ -d $DATADIR ] || {
+ logger -p user.error -t "radicale[----]" "Data directory '$DATADIR' does not exists. Startup failed !!!"
+ exit 1
+ }
+ chgrp -R radicale $DATADIR
+}
+
+boot() {
+ return 0 # will be started by "iface" hotplug events
+}
+
+start() {
+ _running() {
+ sleep 2 # give radicale time to completely come up
+ local _PID=$(eval "$PGREP")
+ kill -1 $_PID 2>/dev/null
+ [ $? -eq 0 ] \
+ && logger -p user.notice -t "radicale[$_PID]" "Service started successfully"\
+ || logger -p user.warn -t "radicale[----]" "Service failed to start"
+ }
+
+ # if already running do nothing
+ local _PID=$(eval "$PGREP")
+ kill -1 $_PID 2>/dev/null && return 0
+
+ _uci2radicale
+ _set_permission
+
+ radicale --daemon --config=$SYSCFG
+
+ _running & # check if running and syslog
+
+ return 0
+}
+
+reload() {
+ # reload is also used by luci
+ local _PID=$(eval "$PGREP")
+ kill -1 $_PID 2>/dev/null
+ if [ $? -eq 0 ]; then
+ # only restart if already running
+ restart
+ else
+ # only start if enabled
+ enabled && start
+ fi
+ return 0
+}
+
+stop() {
+ local _PID=$(eval "$PGREP")
+ [ -z "$_PID" ] && return 0 # not running
+ kill -15 $_PID 2>/dev/null
+ sleep 1 # give time to shutdown
+ local _tmp=$(eval "$PGREP")
+ if [ -z "$_tmp" ]; then
+ logger -p user.notice -t "radicale[$_PID]" "Service shutdown successfully"
+ else
+ kill -9 $_tmp # Normally never come here
+ logger -p user.warn -t "radicale[----]" "Service shutdown FORCED"
+ fi
+ return 0
+}
--- /dev/null
+#
+# Authentication login is matched against the "user" key, and collection's path is matched against the "collection" key.
+# You can use Python's ConfigParser interpolation values %(login)s and %(path)s.
+# You can also get groups from the user regex in the collection with {0}, {1}, etc.
+#
+# For example, for the "user" key, ".+" means "authenticated user" and ".*" means "anybody" (including anonymous users).
+#
+# Section names are only used for naming the rule.
+# Leading or ending slashes are trimmed from collection's path.
+#
+
+# This means all users starting with "admin" may read any collection
+[admin]
+user: ^admin.*$
+collection: .*
+permission: r
+
+# This means all users may read and write any collection starting with public.
+# We do so by just not testing against the user string.
+[public]
+user: .*
+collection: ^public(/.+)?$
+permission: rw
+
+# A little more complex: give read access to users from a domain for all
+# collections of all the users (ie. user@domain.tld can read domain/\*).
+[domain-wide-access]
+user: ^.+@(.+)\..+$
+collection: ^{0}/.+$
+permission: r
+
+# Allow authenticated user to read all collections
+[allow-everyone-read]
+user: .+
+collection: .*
+permission: r
+
+# Give write access to owners
+[owner-write]
+user: .+
+collection: ^%(login)s(/.+)?$
+permission: rw
+
+# Allow CardDavMATE-, CalDavZAP- or InfCloud- WEBclient to work
+# anonymous users have read access to "/" but no files or subdir
+[infcloud]
+user: .*
+collection: /
+permission: r
--- /dev/null
+#
+# Sample File
+#
+
+user1:password1
+user2:password2
\ No newline at end of file
--- /dev/null
+Subject: [PATCH] Run as user radicale and group radicale
+
+Patch to run Radicale service as radicale:radicale non root user
+
+Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
+---
+ bin/radicale | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/bin/radicale b/bin/radicale
+index 619aca5..7466020 100755
+--- a/bin/radicale
++++ b/bin/radicale
+@@ -26,6 +26,13 @@ Launch the server according to configuration and command-line options.
+
+ """
+
++# inserted to run as user radicale
++import pwd, grp, os
++uid = pwd.getpwnam('radicale').pw_uid
++gid = grp.getgrnam('radicale').gr_gid
++os.setegid(gid)
++os.seteuid(uid)
++
+ import radicale.__main__
+
+
+--
+2.1.0
+