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.

356 lines
9.4 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2016-2017 Hsing-wang Liao <kuoruan@gmail.com>
  3. # Licensed to the public under the Apache License 2.0.
  4. START=99
  5. USE_PROCD=1
  6. NAME=aria2
  7. PROG=/usr/bin/aria2c
  8. _info() {
  9. logger -p daemon.info -t "$NAME" "$*"
  10. }
  11. _err() {
  12. logger -p daemon.err -t "$NAME" "$*"
  13. }
  14. _make_dir() {
  15. local d
  16. for d in "$@"; do
  17. if [ ! -d "$d" ]; then
  18. mkdir -p "$d" 2>/dev/null || return 1
  19. fi
  20. done
  21. return 0
  22. }
  23. _create_file() {
  24. touch "$@" 2>/dev/null
  25. }
  26. _change_owner() {
  27. local u="$1"; shift
  28. local d
  29. for d in "$@"; do
  30. if [ -f "$d" ]; then
  31. chown "$u" "$d" 2>/dev/null || return 1
  32. elif [ -d "$d" ]; then
  33. chown -R "$u" "$d" 2>/dev/null || return 1
  34. fi
  35. done
  36. return 0
  37. }
  38. _change_file_mode() {
  39. local mod="$1"; shift
  40. chmod "$mod" "$@" 2>/dev/null
  41. }
  42. _reset_dir_mode() {
  43. local d
  44. for d in "$@"; do
  45. if [ -d "$d" ]; then
  46. find "$d" -type d -exec chmod 755 {} \; 2>/dev/null
  47. find "$d" -type f -exec chmod 644 {} \; 2>/dev/null
  48. fi
  49. done
  50. }
  51. append_options() {
  52. local o; local v
  53. for o in "$@"; do
  54. v="$(eval echo "\$$o")"
  55. [ -n "$v" ] && \
  56. echo "${o//_/-}=$v" >>"$config_file_tmp"
  57. done
  58. }
  59. append_setting() {
  60. local s="$1"
  61. [ -n "$s" ] && \
  62. echo "$s" >>"$config_file_tmp"
  63. }
  64. append_header() {
  65. local h="$1"
  66. [ -n "$h" ] && \
  67. echo "header=\"${h}\"" >>"$config_file_tmp"
  68. }
  69. aria2_validate() {
  70. uci_validate_section "$NAME" aria2 "$1" \
  71. 'enabled:bool:0' \
  72. 'enable_logging:bool' \
  73. 'enable_proxy:bool' \
  74. 'config_dir:string:/var/etc/aria2' \
  75. 'user:string' \
  76. 'all_proxy:string' \
  77. 'all_proxy_passwd:string' \
  78. 'all_proxy_user:string' \
  79. 'auto_save_interval:range(0,600)' \
  80. 'bt_enable_lpd:or("true","false")' \
  81. 'bt_detach_seed_only:or("true","false")' \
  82. 'bt_load_saved_metadata:or("true","false")' \
  83. 'bt_prioritize_piece:string' \
  84. 'bt_max_open_files:uinteger' \
  85. 'bt_max_peers:uinteger' \
  86. 'bt_remove_unselected_file:or("true","false")' \
  87. 'bt_request_peer_speed_limit:string' \
  88. 'bt_save_metadata:or("true","false")' \
  89. 'bt_seed_unverified:or("true","false")' \
  90. 'bt_stop_timeout:uinteger' \
  91. 'bt_tracker:list(string)' \
  92. 'ca_certificate:file' \
  93. 'certificate:file' \
  94. 'check_certificate:or("true","false"):true' \
  95. 'check_integrity:or("true","false")' \
  96. 'connect_timeout:uinteger' \
  97. 'dht_listen_port:string' \
  98. 'dir:string' \
  99. 'disable_ipv6:or("true","false")' \
  100. 'disk_cache:string' \
  101. 'enable_dht:or("true","false"):true' \
  102. 'enable_dht6:or("true","false")' \
  103. 'enable_peer_exchange:or("true","false")' \
  104. 'event_poll:or("epoll","kqueue","port","poll","select")' \
  105. 'file_allocation:or("none","prealloc","trunc","falloc")' \
  106. 'follow_torrent:or("true","false","mem")' \
  107. 'force_save:or("true","false")' \
  108. 'http_accept_gzip:or("true","false")' \
  109. 'http_no_cache:or("true","false")' \
  110. 'listen_port:string' \
  111. 'log:string' \
  112. 'log_level:or("debug","info","notice","warn","error")' \
  113. 'lowest_speed_limit:string' \
  114. 'max_concurrent_downloads:uinteger' \
  115. 'max_connection_per_server:uinteger' \
  116. 'max_download_limit:string' \
  117. 'max_overall_download_limit:string' \
  118. 'max_overall_upload_limit:string' \
  119. 'max_tries:uinteger' \
  120. 'max_upload_limit:string' \
  121. 'min_split_size:string' \
  122. 'pause:or("true","false")' \
  123. 'pause_metadata:or("true","false")' \
  124. 'peer_id_prefix:string' \
  125. 'private_key:file' \
  126. 'retry_wait:uinteger' \
  127. 'rpc_auth_method:or("none","user_pass","token")' \
  128. 'rpc_certificate:file' \
  129. 'rpc_listen_port:range(1024,65535)' \
  130. 'rpc_passwd:string' \
  131. 'rpc_private_key:file' \
  132. 'rpc_secret:string' \
  133. 'rpc_secure:or("true","false")' \
  134. 'rpc_user:string' \
  135. 'save_session_interval:uinteger' \
  136. 'seed_ratio:ufloat' \
  137. 'seed_time:ufloat' \
  138. 'split:uinteger' \
  139. 'timeout:uinteger' \
  140. 'user_agent:string'
  141. }
  142. aria2_start() {
  143. local section="$1"
  144. aria2_validate "$section" || { _err "Validation failed."; return 1; }
  145. [ "$enabled" = "1" ] || { _info "Instance \"${section}\" disabled."; return 1; }
  146. [ -n "$dir" ] || { _err "Please set download dir."; return 1; }
  147. [ -d "$dir" ] || { _err "Please create download dir first."; return 1; }
  148. config_file="${config_dir}/${NAME}.conf.${section}"
  149. config_file_tmp="${config_dir}/${NAME}.conf.tmp"
  150. session_file="${config_dir}/${NAME}.session.${section}"
  151. _make_dir "$config_dir" || {
  152. _err "Can't create config dir: ${config_dir}"
  153. return 1
  154. }
  155. _create_file "$session_file" "$config_file" "$config_file_tmp" || {
  156. _err "Can't create files: ${session_file}, ${config_file}, ${config_file_tmp}"
  157. return 1
  158. }
  159. # create tmp file
  160. cat >"$config_file_tmp" <<-EOF
  161. # Auto generated file, changes to this file will be lost.
  162. EOF
  163. append_setting "dir=${dir}"
  164. append_setting "enable-rpc=true"
  165. append_setting "rpc-allow-origin-all=true"
  166. append_setting "rpc-listen-all=true"
  167. append_setting "quiet=true"
  168. append_setting "continue=true"
  169. append_setting "input-file=${session_file}"
  170. append_setting "save-session=${session_file}"
  171. if [ -z "$enable_logging" ]; then
  172. append_options "log" "log_level"
  173. elif [ "$enable_logging" = "1" ]; then
  174. log=${log:-"/var/log/aria2.log"}
  175. local log_dir
  176. log_dir="$(dirname "$log")"
  177. _make_dir "$log_dir" || {
  178. _err "Can't create log dir: ${log_dir}"
  179. return 1
  180. }
  181. # create or clear log file
  182. echo >"$log"
  183. append_setting "log=${log}"
  184. append_options "log_level"
  185. fi
  186. if [ -z "$enable_proxy" ] || [ "$enable_proxy" = "1" ]; then
  187. append_options "all_proxy" "all_proxy_user" "all_proxy_passwd"
  188. fi
  189. unset_auth_method() {
  190. uci -q batch <<-EOF
  191. set ${NAME}.${section}.rpc_auth_method=""
  192. commit $NAME
  193. EOF
  194. }
  195. if [ -z "$rpc_auth_method" ]; then
  196. if [ -n "$rpc_secret" ]; then
  197. append_setting "rpc-secret=${rpc_secret}"
  198. elif [ -n "$rpc_user" ]; then
  199. append_setting "rpc-user=${rpc_user}"
  200. append_setting "rpc-passwd=${rpc_passwd}"
  201. else
  202. _info "It is recommended to set RPC secret."
  203. fi
  204. elif [ "$rpc_auth_method" = "token" ]; then
  205. if [ -n "$rpc_secret" ]; then
  206. append_setting "rpc-secret=${rpc_secret}"
  207. else
  208. unset_auth_method
  209. fi
  210. elif [ "$rpc_auth_method" = "user_pass" ]; then
  211. if [ -n "$rpc_user" ]; then
  212. append_setting "rpc-user=${rpc_user}"
  213. append_setting "rpc-passwd=${rpc_passwd}"
  214. else
  215. _info "Please set RPC user."
  216. unset_auth_method
  217. fi
  218. fi
  219. if [ ."$rpc_secure" = ."true" ] && [ -n "$rpc_certificate" ]; then
  220. append_setting "rpc-secure=true"
  221. append_options "rpc_certificate" "rpc_private_key"
  222. fi
  223. if [ ."$check_certificate" = ."true" ]; then
  224. append_setting "check-certificate=true"
  225. append_options "ca_certificate"
  226. elif [ ."$check_certificate" = ."false" ]; then
  227. append_setting "check-certificate=false"
  228. fi
  229. if [ ."$enable_dht" = ."true" ]; then
  230. dht_file="${config_dir}/dht.dat.${section}"
  231. _create_file "$dht_file" || {
  232. _err "Can't create DHT file: ${dht_file}"
  233. return 1
  234. }
  235. append_setting "enable-dht=true"
  236. append_setting "dht-file-path=${dht_file}"
  237. fi
  238. if [ ."$enable_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then
  239. dht6_file="${config_dir}/dht6.dat.${section}"
  240. _create_file "$dht6_file" || {
  241. _err "Can't create DHT6 file: ${dht6_file}"
  242. return 1
  243. }
  244. append_setting "enable-dht6=true"
  245. append_setting "dht-file-path6=${dht6_file}"
  246. fi
  247. if [ -n "$bt_tracker" ]; then
  248. local bt_tracker_list; local t
  249. for t in $bt_tracker; do
  250. if [ -z "$bt_tracker_list" ]; then
  251. bt_tracker_list="$t"
  252. else
  253. bt_tracker_list="${bt_tracker_list},${t}"
  254. fi
  255. done
  256. append_setting "bt-tracker=${bt_tracker_list}"
  257. fi
  258. append_options "auto_save_interval" "bt_enable_lpd" "bt_max_open_files" "bt_max_peers" \
  259. "bt_remove_unselected_file" "bt_request_peer_speed_limit" "bt_prioritize_piece" \
  260. "bt_stop_timeout" "bt_detach_seed_only" "bt_save_metadata" "bt_load_saved_metadata" \
  261. "bt_seed_unverified" "certificate" "check_integrity" "connect_timeout" "dht_listen_port" \
  262. "disable_ipv6" "disk_cache" "enable_peer_exchange" "event_poll" "file_allocation" \
  263. "follow_torrent" "force_save" "http_accept_gzip" "http_no_cache" "listen_port" \
  264. "lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" \
  265. "max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \
  266. "max_upload_limit" "min_split_size" "pause" "pause_metadata" "peer_id_prefix" "private_key" \
  267. "retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "split" "timeout" \
  268. "user_agent"
  269. config_list_foreach "$section" "header" append_header
  270. config_list_foreach "$section" "extra_settings" append_setting
  271. sed '/^$/d' "$config_file_tmp" >"$config_file"
  272. rm -f "$config_file_tmp"
  273. _reset_dir_mode "$config_dir"
  274. _change_file_mode 600 "$config_file"
  275. if [ -n "$user" ]; then
  276. if ( user_exists "$user" && _change_owner "$user" "$config_dir" "$log" ); then
  277. _info "Aria2 will run with user '${user}'."
  278. if [ "$user" != "root" ]; then
  279. _info "Please make sure user '${user}' has write access to download dir: ${dir}"
  280. fi
  281. else
  282. _info "Setting run user to '${user}' failed, default user will be used."
  283. user=
  284. fi
  285. fi
  286. procd_open_instance "${NAME}.${section}"
  287. procd_set_param command "$PROG"
  288. procd_append_param command --conf-path="${config_file}"
  289. procd_set_param respawn
  290. procd_set_param stdout 1
  291. procd_set_param stderr 1
  292. procd_set_param file "$config_file"
  293. [ -n "$user" ] && \
  294. procd_set_param user "$user"
  295. procd_add_jail "${NAME}.${section}" log
  296. procd_add_jail_mount "$config_file"
  297. procd_add_jail_mount_rw "$dir" "$config_dir" "$log"
  298. procd_close_instance
  299. }
  300. service_triggers() {
  301. procd_add_reload_trigger "$NAME"
  302. }
  303. start_service() {
  304. config_load "$NAME"
  305. config_foreach aria2_start "aria2"
  306. }