220 lines
6.4 KiB

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