You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
7.5 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2006-2016 OpenWrt.org
  3. START=80
  4. STOP=10
  5. EXTRA_COMMANDS="export_storage"
  6. EXTRA_HELP=" export_storage <PATH>
  7. - export the storage into the specified folder
  8. - <PATH> can be directly used with the default storage backend of Radicale 2.x.x."
  9. CFGDIR=/var/etc/radicale
  10. SYSCFG=$CFGDIR/config
  11. LOGCFG=$CFGDIR/logging
  12. DATADIR="/srv/radicale"
  13. LOGDIR=""
  14. PGREP="ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}' "
  15. # we could start with empty configuration file using defaults
  16. [ -f /etc/config/radicale ] || touch /etc/config/radicale
  17. _uci2radicale() {
  18. local _SYSTMP="$SYSCFG.tmp"
  19. local _LOGTMP="$LOGCFG.tmp"
  20. local _LOPT # list option name
  21. local _LVAL # list option value
  22. local _STYPE # section type
  23. local _SNAME # section name
  24. local _console_level="ERROR" # logging console level
  25. local _file_level="INFO" # logging file level
  26. local _file_path="/var/log/radicale" # logging file path
  27. local _file_maxbytes="8196" # logging file maxBytes
  28. local _file_backupcount="1" # logging file backupCount
  29. local _syslog_level="WARNING" # logging syslog level
  30. # write list values to config
  31. _write_list() {
  32. _write_value "$_LOPT" "$_LVAL" # there might be spaces in _LVAL
  33. _LOPT=""
  34. _LVAL=""
  35. }
  36. _write_value() {
  37. # $1 option
  38. # $2 value
  39. local __OPT=$1
  40. local __VAL=$2
  41. # section "server" ignore option "daemon" and "pid"
  42. [ "$_SNAME" = "server" -a "$__OPT" = "daemon" ] && return 0
  43. [ "$_SNAME" = "server" -a "$__OPT" = "pid" ] && return 0
  44. # section "logging" ignore option "config" (logging config file)
  45. [ "$_SNAME" = "logging" -a "$__OPT" = "config" ] && return 0
  46. # section "auth" ignore option "htpasswd_filename" (htpasswd file)
  47. [ "$_SNAME" = "auth" -a "$__OPT" = "htpasswd_filename" ] && return 0
  48. # section "rights" ignore option "file" (reg-based rights file)
  49. [ "$_SNAME" = "rights" -a "$__OPT" = "file" ] && return 0
  50. # section "headers" replace "_" with "-" in option (UCI problem)
  51. [ "$_SNAME" = "headers" ] && __OPT=$(echo "$__OPT" | sed -e "s#_#-#g")
  52. # save data driectory
  53. [ "$_SNAME" = "storage" -a "$__OPT" = "filesystem_folder" ] && DATADIR="$__VAL"
  54. # special handling for well-known, value needs single quotes
  55. [ "$_SNAME" = "well-known" -a "${__VAL#*\%\(}" != "$__VAL" ] && __VAL="'$__VAL'"
  56. # handling of log settings
  57. if [ "$_STYPE" = "logging" -a "$_SNAME" = "logger" ]; then
  58. eval "_$__OPT='$__VAL'" # set to environment for later use
  59. else
  60. # handle bool
  61. [ "$__VAL" = "0" ] && __VAL="False"
  62. [ "$__VAL" = "1" ] && __VAL="True"
  63. # append data to the corresponding section
  64. sed -i "/\[$_SNAME\]/a $__OPT = $__VAL" $_SYSTMP
  65. fi
  66. }
  67. # redefined callback for sections when calling config_load
  68. config_cb() {
  69. # $1 "Type"
  70. # $2 "Name"
  71. # write out last list option
  72. [ -n "$_LOPT" ] && _write_list
  73. # mark invalid
  74. _STYPE=""
  75. _SNAME=""
  76. # check section type
  77. [ "$1" = "setting" -o "$1" = "logging" ] && {
  78. _STYPE="$1"
  79. _SNAME="$2"
  80. }
  81. # translate section name
  82. [ "$2" = "well_known" ] && _SNAME="well-known"
  83. return 0
  84. }
  85. # redefined callback for lists when calling config_load
  86. list_cb() {
  87. # $1 name of variable
  88. # $2 value
  89. # invalid section type then ignore
  90. [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
  91. # write out last list option if new list starts
  92. [ -n "$_LOPT" -a "$_LOPT" != "$1" ] && _write_list
  93. # new list option
  94. if [ -z "$_LOPT" ]; then
  95. _LOPT="$1"
  96. _LVAL="$2"
  97. else
  98. _LVAL="$_LVAL, $2"
  99. fi
  100. return 0
  101. }
  102. # redefined callback for options when calling config_load
  103. option_cb() {
  104. # $1 name of variable
  105. # $2 value
  106. local __OPT="$1"
  107. local __VAL="$2"
  108. # invalid section type then ignore
  109. [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
  110. # ignore list entrys will be handled by list_cb()
  111. [ "${__OPT#*_ITEM}" != "$__OPT" ] && return 0 # ignore lists *_ITEM*
  112. [ "${__OPT#*_LENGTH}" != "$__OPT" ] && return 0 # ignore lists *_LENGTH
  113. # write out last list option and clear
  114. [ -n "$_LOPT" ] && _write_list
  115. # write to file
  116. _write_value "$__OPT" "$__VAL" # there might be spaces in __VAL
  117. return 0
  118. }
  119. # temporary config file
  120. # radicale need read access
  121. mkdir -m0755 -p $CFGDIR
  122. cp /etc/radicale/config.template $_SYSTMP
  123. config_load radicale # calling above config_cb()/option_cb()/list_cb() and write into $_SYSTMP
  124. sed -i "/\[logging\]/a config = /var/etc/radicale/logging" $_SYSTMP # hard-code logging config
  125. sed -i "/\[auth\]/a htpasswd_filename = /etc/radicale/users" $_SYSTMP # hard-code htpasswd
  126. sed -i "/\[rights\]/a file = /etc/radicale/rights" $_SYSTMP # hard-code regexp-based rights
  127. # temporary logging config file
  128. cp /etc/radicale/logging.template $_LOGTMP
  129. LOGDIR="$_file_path"
  130. sed -i "/\[handler_console\]/a level = $_console_level" $_LOGTMP
  131. sed -i "/\[handler_file\]/a level = $_file_level" $_LOGTMP
  132. sed -i "/\[handler_file\]/a args = ('$_file_path/radicale','a',$_file_maxbytes,$_file_backupcount)" $_LOGTMP
  133. sed -i "/\[handler_syslog\]/a level = $_syslog_level" $_LOGTMP
  134. # move tmp to final
  135. mv -f $_SYSTMP $SYSCFG
  136. mv -f $_LOGTMP $LOGCFG
  137. }
  138. _set_permission() {
  139. # config file permissions (read access for group)
  140. chmod 644 $SYSCFG $LOGCFG
  141. chgrp -R radicale $CFGDIR
  142. # log directory (full access and owner)
  143. [ -d $LOGDIR ] || mkdir -m0755 -p $LOGDIR
  144. chown -R radicale:radicale $LOGDIR
  145. # data directory does not exist
  146. [ -d $DATADIR ] || {
  147. logger -p user.error -t "radicale[----]" "Data directory '$DATADIR' does not exists. Startup failed !!!"
  148. exit 1
  149. }
  150. chgrp -R radicale $DATADIR
  151. }
  152. export_storage() {
  153. # if already running do nothing
  154. local _PID=$(eval "$PGREP")
  155. kill -1 $_PID 2>/dev/null && {
  156. echo "Export failed !!! - Service running !" >&2
  157. logger -p user.error -t "radicale[$_PID]" "Export failed !!! - Service running !"
  158. return 1
  159. }
  160. [ $# -ne 1 ] || [ ! -d $1 ] && {
  161. echo "Export failed !!! Directory not given or does not exist !" >&2
  162. logger -p user.error -t "radicale[----]" "Export failed !!! Directory not given or does not exist !"
  163. return 1
  164. }
  165. _uci2radicale
  166. _set_permission
  167. chmod 775 $1
  168. chgrp radicale $1
  169. radicale --config=$SYSCFG --export-storage $1/export
  170. }
  171. boot() {
  172. # wait a given time (default 10 seconds) before startup
  173. # to wait for interfaces to come up / not using hotplug events during boot
  174. _start() {
  175. [ $1 -gt 0 ] && sleep $1
  176. start
  177. }
  178. local _DELAY
  179. _DELAY=$(uci_get "radicale" "system" "boot_delay" "10")
  180. _start $_DELAY &
  181. return 0
  182. }
  183. shutdown() {
  184. rm -f /tmp/radicale.hotplug
  185. stop
  186. }
  187. start() {
  188. _running() {
  189. sleep 2 # give radicale time to completely come up
  190. local _PID=$(eval "$PGREP")
  191. kill -1 $_PID 2>/dev/null
  192. [ $? -eq 0 ] \
  193. && logger -p user.notice -t "radicale[$_PID]" "Service started successfully"\
  194. || logger -p user.warn -t "radicale[----]" "Service failed to start"
  195. }
  196. # if already running do nothing
  197. local _PID=$(eval "$PGREP")
  198. kill -1 $_PID 2>/dev/null && return 0
  199. _uci2radicale
  200. _set_permission
  201. radicale --daemon --config=$SYSCFG
  202. touch /tmp/radicale.hotplug
  203. _running & # check if running and syslog
  204. return 0
  205. }
  206. reload() {
  207. # reload is also used by luci
  208. local _PID=$(eval "$PGREP")
  209. kill -1 $_PID 2>/dev/null
  210. if [ $? -eq 0 ]; then
  211. # only restart if already running
  212. restart
  213. else
  214. # only start if enabled
  215. enabled && start
  216. fi
  217. return 0
  218. }
  219. stop() {
  220. local _PID=$(eval "$PGREP")
  221. [ -z "$_PID" ] && return 0 # not running
  222. kill -15 $_PID 2>/dev/null
  223. sleep 3 # give time to shutdown
  224. local _tmp=$(eval "$PGREP")
  225. if [ -z "$_tmp" ]; then
  226. logger -p user.notice -t "radicale[$_PID]" "Service shutdown successfully"
  227. else
  228. kill -9 $_tmp # Normally never come here
  229. logger -p user.warn -t "radicale[----]" "Service shutdown FORCED"
  230. fi
  231. return 0
  232. }