· 9 years ago · Apr 05, 2017, 08:26 PM
1#!/bin/sh
2# ***** BEGIN LICENSE BLOCK *****
3# Version: MPL 1.1
4#
5# The contents of this file are subject to the Mozilla Public License Version
6# 1.1 (the "License"); you may not use this file except in compliance with
7# the License. You may obtain a copy of the License at
8# http://www.mozilla.org/MPL/
9#
10# Software distributed under the License is distributed on an "AS IS" basis,
11# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12# for the specific language governing rights and limitations under the
13# License.
14#
15# The Original Code is IRC Auto Downloader
16#
17# The Initial Developer of the Original Code is
18# David Nilsson.
19# Portions created by the Initial Developer are Copyright (C) 2010, 2011
20# the Initial Developer. All Rights Reserved.
21#
22# Contributor(s):
23#
24# ***** END LICENSE BLOCK *****
25
26AUTODL_IRSSI_ZIP_URL="https://github.com/autodl-community/autodl-irssi/archive/master.zip"
27GIT_PATH_RUTORRENT_PLUGIN="https://github.com/autodl-community/autodl-rutorrent.git"
28
29WEBMIN_URL="https://netix.dl.sourceforge.net/project/webadmin/webmin/1.830/webmin-1.830.tar.gz"
30
31# RUTORRENT_TRUNK_DIR="https://rutorrent.googlecode.com/svn/trunk"
32RUTORRENT_TRUNK_DIR="https://github.com/Novik/ruTorrent.git"
33
34# The official tarballs are tried if git fails.
35RUTORRENT_VERSION="3.7"
36RUTORRENT_CORE_NAME="rutorrent-$RUTORRENT_VERSION.tar.gz"
37RUTORRENT_CORE_URL="http://dl.bintray.com/novik65/generic/$RUTORRENT_CORE_NAME"
38#RUTORRENT_CORE_URL="http://rutorrent.googlecode.com/files/$RUTORRENT_CORE_NAME"
39RUTORRENT_PLUGINS_NAME="plugins-$RUTORRENT_VERSION.tar.gz"
40#RUTORRENT_PLUGINS_URL="http://rutorrent.googlecode.com/files/$RUTORRENT_PLUGINS_NAME"
41RUTORRENT_PLUGINS_URL="http://dl.bintray.com/novik65/generic/$RUTORRENT_PLUGINS_NAME"
42#RUTORRENT_CORE_URL2="http://sourceforge.net/projects/autodl-irssi/files/inst-files/$RUTORRENT_CORE_NAME/download"
43#RUTORRENT_PLUGINS_URL2="http://sourceforge.net/projects/autodl-irssi/files/inst-files/$RUTORRENT_PLUGINS_NAME/download"
44
45RUTORRENT_PLUGINS=
46
47# These are the ruTorrent plugins that will get installed. To remove one, either
48# remove the whole line or comment it (prepend a '#' to the start of the line).
49# If the line starts with '#', the plugin is not installed.
50RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS _getdir"
51RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS _noty2"
52RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS _task"
53RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS autotools"
54RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS check_port"
55RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS chunks"
56RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS cookies"
57RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS cpuload"
58RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS create"
59RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS data"
60RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS datadir"
61RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS diskspace"
62RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS edit"
63RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS erasedata"
64RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS extratio"
65RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS extsearch"
66RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS feeds"
67RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS filedrop"
68RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS geoip"
69RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS history"
70RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS httprpc"
71RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS ipad"
72RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS loginmgr"
73RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS lookat"
74RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS mediainfo"
75RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS ratio"
76RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS retrackers"
77#RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS rpc"
78RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS rss"
79RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS rssurlrewrite"
80RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS rutracker_check"
81RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS scheduler"
82RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS screenshots"
83RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS seedingtime"
84RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS show_peers_like_wtorrent"
85RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS source"
86RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS theme"
87RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS throttle"
88RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS tracklabels"
89RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS trafic"
90RUTORRENT_PLUGINS="$RUTORRENT_PLUGINS unpack"
91
92
93# For building rtorrent
94LIBCURL_NAME="curl-7.52.1"
95LIBCURL_URL="http://curl.haxx.se/download/$LIBCURL_NAME.tar.gz"
96SIGCPP20_NAME="libsigc++-2.10.0"
97SIGCPP20_URL="http://ftp.acc.umu.se/pub/GNOME/sources/libsigc++/2.10/$SIGCPP20_NAME.tar.gz"
98XMLRPC_SVN_DIR="https://svn.code.sf.net/p/xmlrpc-c/code/stable"
99LIBTORRENT_VERSION="0.13.6"
100LIBTORRENT_NAME="libtorrent-$LIBTORRENT_VERSION"
101LIBTORRENT_URL="http://rtorrent.net/downloads/$LIBTORRENT_NAME.tar.gz"
102#LIBTORRENT_URL2="http://sourceforge.net/projects/autodl-irssi/files/inst-files/$LIBTORRENT_NAME.tar.gz/download"
103RTORRENT_VERSION="0.9.6"
104RTORRENT_NAME="rtorrent-$RTORRENT_VERSION"
105RTORRENT_URL="http://rtorrent.net/downloads/$RTORRENT_NAME.tar.gz"
106#RTORRENT_URL2="http://sourceforge.net/projects/autodl-irssi/files/inst-files/$RTORRENT_NAME.tar.gz/download"
107
108HTPASSWD_PY_SCRIPT_URL="http://trac.edgewall.org/export/10433/trunk/contrib/htpasswd.py"
109HTPASSWD_PY_SCRIPT_URL2="http://sourceforge.net/projects/autodl-irssi/files/inst-files/htpasswd.py/download"
110
111NGINX_NAME="nginx-1.11.9"
112NGINX_URL="http://nginx.org/download/$NGINX_NAME.tar.gz"
113
114LIGHTTPD_NAME="lighttpd-1.4.45"
115LIGHTTPD_URL="http://download.lighttpd.net/lighttpd/releases-1.4.x/$LIGHTTPD_NAME.tar.gz"
116
117MOD_SCGI_VERSION="1.15"
118MOD_SCGI_URL="http://python.ca/scgi/releases/scgi-$MOD_SCGI_VERSION.tar.gz"
119
120UNRAR_VERSION="5.4.5"
121UNRAR_URL="http://www.rarlab.com/rar/unrarsrc-$UNRAR_VERSION.tar.gz"
122
123# Dirs relative to user's home directory
124RTORRENT_REL_DOWNLOAD_DIR="downloads"
125RTORRENT_REL_WATCH_DIR="rtorrent/watch"
126RTORRENT_REL_SESSION_DIR="rtorrent/session"
127
128REQUIRED_PERL_MODULES="Time::HiRes XML::LibXML Archive::Zip Net::SSLeay HTML::Parser Digest::SHA JSON"
129REQUIRED_PHP_MODULES="json xml sockets"
130
131# If set to y, add 'load perl' to .irssi/startup
132IRSSI_LOAD_PERL=n
133IGNORE_IRSSI=n
134
135# Start port. When we need a new port number, this port is incremented by one.
136CURRENT_PORT=23875
137DEFAULT_PORT_FTP=21
138DEFAULT_PORT_FTPES=990
139DEFAULT_UMASK=022
140RPC_PREFIX=RPC
141
142LSB_DEFAULT_START="2 3 4 5"
143LSB_DEFAULT_STOP="0 1 6"
144
145# Setting these to anything other than 80 and 443 may not work with Apache (since the
146# code assumed it would always be 80 and 443).
147HTTP_PORT=80
148HTTPS_PORT=443
149
150SCGI_HOST="127.0.0.1"
151
152INTERACTIVE=n
153USE_RUTORRENT_PLUGIN=n
154REINSTALL_RUTORRENT_PLUGIN=n
155INSTALL_AUTODL_IRSSI=n
156RUTORRENT_PASSWORD_PROTECTED=n
157USERS=
158RUTORRENT_BASE_PATH=
159INSTALL_STARTUP_SCRIPT=n
160BUILD_RTORRENT=n
161INSTALL_WEB_SERVER=
162INSTALL_RUTORRENT=n
163INSTALL_VSFTPD=n
164FTP_PORT=
165USE_ENCRYPTED_FTP=n
166INSTALL_WEBMIN=n
167USER_TIMEZONE=
168
169RUTORRENT_SITE_REALM="My ruTorrent web site"
170AUTODL_STARTUP_DESC="Start autodl-irssi and rtorrent"
171PHPCGI_STARTUP_DESC="Start php-cgi"
172NGINX_STARTUP_DESC="Start nginx"
173LIGHTTPD_STARTUP_DESC="Start lighttpd"
174
175PATH="$PATH:/usr/local/bin"
176
177# Find an echo that supports -e
178echo=echo
179for cmd in echo /bin/echo; do
180 $cmd >/dev/null 2>&1 || continue
181 if ! $cmd -e "" | grep -qE '^-e'; then
182 echo=$cmd
183 break
184 fi
185done
186
187CSI=$($echo -e "\033[")
188CEND="${CSI}0m"
189CDGREEN="${CSI}32m"
190CRED="${CSI}1;31m"
191CGREEN="${CSI}1;32m"
192CYELLOW="${CSI}1;33m"
193CBLUE="${CSI}1;34m"
194CMAGENTA="${CSI}1;35m"
195CCYAN="${CSI}1;36m"
196CQUESTION="$CMAGENTA"
197CWARNING="$CRED"
198CMSG="$CCYAN"
199
200errorExit() {
201 cat << EOF
202$CWARNING
203***ERROR***
204$*
205***ERROR***
206$CEND
207Help channel: ${CGREEN}#autodl-community@irc.p2p-network.net$CEND
208EOF
209 exit 1
210}
211
212exitHelp() {
213 cat << EOF
214
215autodl-irssi and ruTorrent plugin installer
216
217 sh $0 [options]
218
219Options:
220
221--rtorrent
222 Will build and install rtorrent, libtorrent and xmlrpc-c from source code.
223
224--rtorrent-noexec-patch
225 Patch rtorrent to disallow remote users from executing code.
226
227--apache
228 Install Apache web server.
229
230--nginx
231 Install nginx web server.
232
233--lighttpd
234 Install lighttpd web server.
235
236--rutorrent
237 Install ruTorrent. Requires a web server, eg. --apache.
238
239--vsftpd
240 Install vsftpd.
241
242--ftpes
243 Use encrypted FTP (FTPES).
244
245--ftp-port <port>
246 FTP server port.
247
248--webmin
249 Install Webmin.
250
251-p
252--rutorrent-plugin
253 Use or install the autodl-irssi ruTorrent plugin. If it's already installed,
254 it will be updated (svn up), unless --reinstall-plugin option is used in
255 which case it will be re-installed.
256
257-i
258--reinstall-plugin
259 Re-install the autodl-irssi ruTorrent plugin if it's already installed.
260
261-a
262--install-autodl
263 Install autodl-irssi.
264
265-u user:autodlPass:webUser:webPass
266--user user:autodlPass:webUser:webPass
267 The $(uname -s) user, autodl-irssi password, ruTorrent user, ruTorrent password.
268 You can use more than one -u option. If autodlPassword is not set, a random
269 password will be used.
270
271-w
272--password-protected
273 Use this option if ruTorrent is password protected. It's required if you
274 want to use more than one ruTorrent user. Not needed if you install
275 ruTorrent.
276
277-r PATH
278--rutorrent-base-path PATH
279 Path to ruTorrent, eg. /var/www/rutorrent. Not needed if you install
280 ruTorrent.
281
282-s
283--install-startup-script
284 Install a startup script (service) which will start Irssi and rtorrent when
285 the computer boots.
286
287-h
288--help
289 Show this help text
290
291Examples (as root user):
292
293 sh $0 --rtorrent --apache --rutorrent --vsftpd --ftpes --webmin -p -a -s -u user1::user1:pass1 -u user2::user2:pass2
294
295Installs rtorrent, Apache, ruTorrent, vsftpd (encrypted), Webmin the
296autodl-irssi plugin, autodl-irssi, installs a service (starting Irssi and
297rtorrent) for both users.
298
299 sh $0 -p -a -u user::user:pass -r /var/www/rutorrent -s
300
301Installs autodl-irssi + ruTorrent plugin for user 'user'. ruTorrent has not been
302password protected. Also installs the startup script.
303
304 sh $0 -p -a -u user1::user1:pass1 -u user2::user2:pass2 -w -r /var/www/rutorrent -s
305
306Installs autodl-irssi + ruTorrent plugin for users 'user1' and 'user2'.
307ruTorrent has been password protected. Also installs the startup script.
308
309 sh $0 --rtorrent -a -u user1 -u user2 -u user3 -u user4 -s
310
311Installs rtorrent, autodl-irssi and the startup script.
312
313Help fchannel: #autodl-community@irc.p2p-network.net
314EOF
315 exit 1
316}
317
318parseCommandLine() {
319 while [ $# -gt 0 ]; do
320 local arg="$1"
321 shift
322
323 if [ "$arg" = "-p" ] || [ "$arg" = "--rutorrent-plugin" ]; then
324 USE_RUTORRENT_PLUGIN=y
325 elif [ "$arg" = "-i" ] || [ "$arg" = "--reinstall-plugin" ]; then
326 REINSTALL_RUTORRENT_PLUGIN=y
327 elif [ "$arg" = "-a" ] || [ "$arg" = "--install-autodl" ]; then
328 INSTALL_AUTODL_IRSSI=y
329 elif [ "$arg" = "-u" ] || [ "$arg" = "--user" ]; then
330 USERS="$USERS $1"
331 shift
332 elif [ "$arg" = "-w" ] || [ "$arg" = "--password-protected" ]; then
333 RUTORRENT_PASSWORD_PROTECTED=y
334 elif [ "$arg" = "-r" ] || [ "$arg" = "--rutorrent-base-path" ]; then
335 RUTORRENT_BASE_PATH="$1"
336 shift
337 elif [ "$arg" = "-s" ] || [ "$arg" = "--install-startup-script" ]; then
338 INSTALL_STARTUP_SCRIPT=y
339 elif [ "$arg" = "--rtorrent" ]; then
340 BUILD_RTORRENT=y
341 elif [ "$arg" = "--apache" ]; then
342 INSTALL_WEB_SERVER=apache
343 elif [ "$arg" = "--nginx" ]; then
344 INSTALL_WEB_SERVER=nginx
345 elif [ "$arg" = "--lighttpd" ]; then
346 INSTALL_WEB_SERVER=lighttpd
347 elif [ "$arg" = "--rutorrent" ]; then
348 INSTALL_RUTORRENT=y
349 elif [ "$arg" = "--vsftpd" ]; then
350 INSTALL_VSFTPD=y
351 elif [ "$arg" = "--ftpes" ]; then
352 USE_ENCRYPTED_FTP=y
353 elif [ "$arg" = "--ftp-port" ]; then
354 FTP_PORT="$1"
355 shift
356 elif [ "$arg" = "--webmin" ]; then
357 INSTALL_WEBMIN=y
358 else
359 exitHelp
360 fi
361 done
362}
363
364# Sets os and os_long to the OS type and OS name respectively
365detectOs() {
366 local DISTRIB_ID=
367 local DISTRIB_DESCRIPTION=
368 if [ -f /etc/lsb-release ]; then
369 . /etc/lsb-release
370 fi
371
372 if [ -f /etc/fedora-release ]; then
373 os=fedora
374 os_long="$(cat /etc/fedora-release)"
375 # Must be before a whole bunch of other OS tests
376 elif [ "$DISTRIB_ID" = "Ubuntu" ]; then
377 os=debian
378 os_long="$DISTRIB_DESCRIPTION"
379 elif [ "$DISTRIB_ID" = "LinuxMint" ]; then
380 os=debian
381 os_long="$DISTRIB_DESCRIPTION"
382 # Must be before Debian
383 elif [ "$DISTRIB_ID" = "Peppermint" ]; then
384 os=debian
385 os_long="$DISTRIB_DESCRIPTION"
386 elif [ "$DISTRIB_ID" = "MEPIS" ]; then
387 os=debian
388 os_long="$DISTRIB_DESCRIPTION"
389 elif [ -f /etc/clearos-release ]; then
390 os=fedora
391 os_long="$(cat /etc/clearos-release)"
392 elif [ -f /etc/debian_version ]; then
393 os=debian
394 local prefix=
395 if ! uname -s | grep -q GNU; then
396 prefix="GNU/"
397 fi
398 os_long="Debian $prefix$(uname -s) $(cat /etc/debian_version)"
399 elif [ -f /etc/redhat-release ]; then
400 os=fedora
401 os_long="$(cat /etc/redhat-release)"
402 else
403 echo -e "\e[1;31mYour OS is not detected as an OS supported by this script. This script only supports \e[5;32mDebian and Fedora\e[0m \e[1;31mbased OSes.\e[0m"
404 exit 1
405
406 fi
407
408 os_long="${os_long:-$(uname -s)}"
409}
410
411# In-place editing like sed -i but more portable...
412sed_i() {
413 local cmd="$1"
414 local file="$2"
415 isProgramInstalled ed || errorExit "ed is not installed!"
416 local addr=","
417 echo "$cmd" | grep -qE '^/' && addr=
418 ed -s "$file" > /dev/null 2>&1 << EOF
419$addr$cmd
420w
421q
422EOF
423}
424
425getFirst() {
426 echo $1
427}
428
429# Returns true if $1 is one of $2..$n
430arrayIsPresent() {
431 local val="$1"
432 shift
433 for v in "$@"; do
434 [ "$v" = "$val" ] && return 0
435 done
436 return 1
437}
438
439canGeneratePasswords() {
440 [ -c /dev/urandom ]
441}
442
443generatePassword() {
444 newPassword=$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c17)
445}
446
447isProgramInstalled() {
448 which "$1" > /dev/null 2>&1 && return 0
449 return 1
450}
451
452isPerlModuleInstalled() {
453 perl -M$1 -e '' > /dev/null 2>&1 && return 0
454 return 1
455}
456
457# Add $1 or $2 if it exists, to PACKAGES if program $1 isn't present
458addProgram() {
459 isProgramInstalled $1 || PACKAGES="$PACKAGES ${2:-$1}"
460}
461
462# Add $2 to PACKAGES if perl module $1 isn't present
463addPerlModule() {
464 isPerlModuleInstalled $1 || PACKAGES="$PACKAGES $2"
465}
466
467installPackages() {
468 [ -z "$INSTALL" ] && return
469 [ -z "$PACKAGES" ] && return
470 $INSTALL $PACKAGES
471 PACKAGES=
472}
473
474installPerlModule() {
475 isPerlModuleInstalled $1 || $INSTALL $2
476}
477
478installProgram() {
479 isProgramInstalled $1 || $INSTALL ${2:-$1}
480}
481
482installBuildTools() {
483 [ "$BUILD_TOOLS_INSTALLED" = y ] && return
484 PACKAGES="$BUILD_TOOLS"
485 installPackages
486 BUILD_TOOLS_INSTALLED=y
487}
488
489# Detects missing Perl modules and stores them in MISSING_PERL_MODULES
490detectMissingPerlModules() {
491 OLD_PERL_MODULES=
492 MISSING_PERL_MODULES=
493 for module in $REQUIRED_PERL_MODULES; do
494 isPerlModuleInstalled $module || MISSING_PERL_MODULES="$MISSING_PERL_MODULES $module"
495 done
496
497 # Make sure the JSON module is new
498 if isPerlModuleInstalled JSON && ! perl -MJSON -e '&decode_json("{}")' > /dev/null 2>&1; then
499 echo "${CWARNING}Old JSON module is installed. Need to install from CPAN.$CEND"
500 MISSING_PERL_MODULES="$MISSING_PERL_MODULES JSON"
501 OLD_PERL_MODULES="$OLD_PERL_MODULES JSON"
502 fi
503
504 if echo "$MISSING_PERL_MODULES" | grep -wq JSON; then
505 MISSING_PERL_MODULES="JSON::XS $MISSING_PERL_MODULES"
506 fi
507 if echo "$MISSING_PERL_MODULES" | grep -q 'XML::LibXML'; then
508 # Sometimes the cpan script doesn't install the required dependencies
509 MISSING_PERL_MODULES="XML::NamespaceSupport XML::SAX $MISSING_PERL_MODULES"
510 fi
511}
512
513# Detect where cpan is installed and place the path in the CPAN variable.
514# PCLinuxOS/Mandriva append the version number...
515detectCpanBin() {
516 for file in $(which cpan 2> /dev/null) $(ls /usr/bin/cpan-* 2> /dev/null); do
517 if [ -x "$file" ]; then
518 CPAN="$file"
519 return
520 fi
521 done
522 isPerlModuleInstalled CPAN && return
523 errorExit "Could not find the cpan script or the CPAN Perl module. Can't install missing Perl modules."
524}
525
526isValidTzName() {
527 echo "$1" | LC_ALL=C grep -qE '^[A-Z][^/ ]*(/[A-Z][^/ ]*)?$' && return 0
528 return 1
529}
530
531detectTimeZone() {
532 [ -n "$USER_TIMEZONE" ] && return
533
534 local hash=
535 local hasher=
536 local files=
537 local zoneinfoPath=/usr/share/zoneinfo
538 [ -d "$zoneinfoPath" ] || return
539 if hasher=md5sum; isProgramInstalled $hasher || hasher=sha1sum; isProgramInstalled $hasher; then
540 hash=$($hasher /etc/localtime | awk '{print $1}')
541 files="$(find $zoneinfoPath -type f -print | xargs $hasher | grep -E "^$hash\\>" | awk '{print $2}')"
542 elif hasher=md5; isProgramInstalled $hasher || hasher=sha1; isProgramInstalled $hasher; then
543 hash=$($hasher /etc/localtime | sed -e 's/^.* = \([a-zA-Z0-9]*\)$/\1/')
544 files="$(find $zoneinfoPath -type f -print | xargs $hasher | grep -E "$hash\$" | sed -e 's/^[^ ]* (\([^)]*\)).*/\1/')"
545 else
546 return
547 fi
548
549 # Detect all possible timezone names
550 local timezones=
551 for path in $files; do
552 local tz="${path#$zoneinfoPath/}"
553 while true; do
554 isValidTzName "$tz" && break
555 local newTz="${tz#*/}"
556 [ "$newTz" = "$tz" ] && tz= && break
557 tz="$newTz"
558 done
559 isValidTzName "$tz" && timezones="$timezones $tz"
560 done
561
562 # Now find the ones PHP likes...
563 local okRegions="(Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)"
564 for tz in $timezones; do
565 echo "$tz" | grep -qE "^$okRegions/" && USER_TIMEZONE="$tz" && return
566 done
567
568 # Return the first one we found
569 for tz in $timezones; do
570 USER_TIMEZONE="$tz"
571 return
572 done
573}
574
575getNumCpus() {
576 [ -n "$NUMCPUS" ] && return
577 [ -f /proc/cpuinfo ] && NUMCPUS=$(cat /proc/cpuinfo | grep '^processor' | wc -l) && return
578 isProgramInstalled sysctl && sysctl -n hw.ncpu | grep -qE '^[1-9][0-9]*$' && NUMCPUS=$(sysctl -n hw.ncpu) && return
579 NUMCPUS=1
580}
581
582# Appends $value to $varName in $file, creating the var if it doesn't exist. The
583# value is not appended if it already exists.
584appendFileStringVar() {
585 local file="$1"
586 local varName="$2"
587 local value="$3"
588
589 [ -f "$file" ] || errorExit "File '$file' does not exist"
590
591 local varLine=$(grep -E "^$varName=" "$file" | tail -n1)
592 if [ -z "$varLine" ]; then
593 echo "$varName=\"$value\"" >> "$file"
594 else
595 echo "$varLine" | grep -qE "[='\" ]$value(\"|'| |$)" && return
596
597 local q=
598 echo "$varLine" | grep -qE "^$varName='" && q="'"
599 echo "$varLine" | grep -qE "^$varName=\"" && q='"'
600 sed_i "s#^\\($varName=\\)$q\\(.*\\)$q#\\1\"\\2 $value\"#" "$file"
601 fi
602}
603
604# Set a variable in a script file to a new value. The variable is created if it does not exist
605setScriptVariable() {
606 local file="$1"
607 local name=$2
608 local value="$3"
609
610 [ -f "$file" ] || errorExit "File does not exist: $file"
611
612 local newLine="$name=\"$value\""
613 if grep -qE "^$name=" $file; then
614 sed_i "s!^$name=.*\$!$newLine!" "$file"
615 else
616 echo "$newLine" >> "$file"
617 fi
618}
619
620userExists() {
621 id -rg "$1" > /dev/null 2>&1 && return 0
622 return 1
623}
624
625setSvnOpts() {
626 SVN_OPTS=
627 isProgramInstalled svn || return
628 # svn sometimes gives an error message 'broken pipe'. Ignore it.
629 if svn help co 2>/dev/null | grep -q 'non-interactive' && svn help co 2>/dev/null | grep -q 'trust-server-cert'; then
630 SVN_OPTS="--non-interactive --trust-server-cert"
631 fi
632}
633
634downloadFile() {
635 local filename="$1"
636 shift
637 for url in "$@"; do
638 for i in 1 2 3 4 5; do
639 wget --no-check-certificate -O "$filename" "$url" && return 0
640 done
641 done
642 return 1
643}
644
645buildMakeProgram() {
646 local url="$1"
647 local name="$2"
648 local builddir="$3"
649 local srcdir="$4"
650 local makefile="${5:-Makefile}"
651
652 buildStart
653 echo "${CMSG}Downloading $name source code...$CEND"
654 cd "$BUILD_DIR"
655 local filename="${url##*/}"
656 downloadFile "$filename" "$url" || errorExit "Could not download $name source code."
657 tar xzf "$filename"
658 srcdir="${srcdir:-${filename%.tar.gz}}"
659 cd "$srcdir/$builddir"
660 local make=${MAKE:-make}
661 echo "${CMSG}Building $name...$CEND"
662 $make -f $makefile all || errorExit "Could not build $name."
663 $make -f $makefile install || errorExit "Could not install $name."
664 echo "${CMSG}$name is now installed$CEND"
665 buildEnd
666}
667
668buildProgram() {
669 local prog="$1"
670
671 echo "${CMSG}Building $prog...$CEND"
672
673 ./configure --prefix=$PREFIX $2 || errorExit "Could not configure $prog. Try again, or try logging out and in and try again."
674
675 getNumCpus
676 local make=${MAKE:-make}
677 local makeopts="-j$NUMCPUS"
678 $make $makeopts || $make || errorExit "Could not build $prog"
679 $make install || errorExit "Could not install $prog"
680
681 local ldsoconf=/etc/ld.so.conf
682 touch "$ldsoconf"
683 grep -qE "^$PREFIX/lib$" $ldsoconf || echo "$PREFIX/lib" >> $ldsoconf
684 ldconfig || errorExit "ldconfig failed"
685
686 echo "${CMSG}$prog is now installed.$CEND"
687}
688
689downloadAndBuild() {
690 local prog="$1"
691 local urls="$2"
692 local name="$3"
693 local configOptions="$4"
694 local patchUrl="$5"
695
696 cd "$BUILD_DIR"
697 echo "${CMSG}Downloading $prog source code...$CEND"
698 downloadFile "$name.tar.gz" $urls || errorExit "Could not download $prog source code."
699 tar xzf $name.tar.gz
700
701 if echo "$patchUrl" | grep '^[a-z]*://'; then
702 echo "${CMSG}Patching $prog...$CEND"
703 PACKAGES="patch"
704 installPackages
705 isProgramInstalled patch || errorExit "patch is not installed!"
706 downloadFile the.patch "$patchUrl" || errorExit "Could not download the patch file."
707 patch -p1 -d $name < the.patch || errorExit "Could not patch $prog."
708 elif [ -n "$patchUrl" ]; then
709 echo "${CMSG}Patching $prog...$CEND"
710 cd $name
711 eval $patchUrl
712 cd ..
713 fi
714
715 cd $name
716 buildProgram "$prog" "$configOptions"
717}
718
719checkoutAndBuild() {
720 local prog="$1"
721 local url="$2"
722 local configOptions="$3"
723 cd "$BUILD_DIR"
724 echo "${CMSG}Downloading $prog source code...$CEND"
725 svn export $SVN_OPTS "$url" "$prog" || errorExit "Could not download $prog source code."
726 cd "$prog"
727 buildProgram "$prog" "$configOptions"
728}
729
730buildStart() {
731 PREFIX=/usr/local
732 OLD_PATH="$PATH"
733 PATH="$PATH:$PREFIX/bin"
734 PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig
735 export PKG_CONFIG_PATH
736 BUILD_DIR="$(echo ~)/build-tmp"
737
738 rm -rf "$BUILD_DIR"
739 mkdir "$BUILD_DIR" || errorExit "Could not create build directory."
740}
741
742buildEnd() {
743 cd
744 rm -rf "$BUILD_DIR"
745
746 [ -n "$OLD_PATH" ] && PATH="$OLD_PATH"
747 unset OLD_PATH
748 unset PKG_CONFIG_PATH
749}
750
751buildRtorrent() {
752 installBuildTools
753 osHandler_$os installRtorrentBuildTools
754 isProgramInstalled pkg-config || errorExit "pkg-config is not installed."
755
756 # Minimum version is 7.15.4 but I had problems with 7.15.5 on CentOS. Set
757 # it to 7.18.0 (the version Ubuntu Server 8.04 is using).
758 if ! pkg-config --atleast-version=7.18.0 libcurl; then
759 downloadAndBuild "libcurl" "$LIBCURL_URL" "$LIBCURL_NAME" ""
760 # Prevent 'Unknown keyword 'URL' in ....' error
761 sed_i 's/^URL:/#URL:/' $PREFIX/lib/pkgconfig/libcurl.pc
762 fi
763 if ! pkg-config --exists sigc++-2.0; then
764 downloadAndBuild "sigc++-2.0" "$SIGCPP20_URL" "$SIGCPP20_NAME" ""
765 fi
766 checkoutAndBuild "xmlrpc-c" "$XMLRPC_SVN_DIR" "--disable-cplusplus"
767 downloadAndBuild "libtorrent" "$LIBTORRENT_URL $LIBTORRENT_URL2" "$LIBTORRENT_NAME" "" patchLibtorrent
768 downloadAndBuild "rtorrent" "$RTORRENT_URL $RTORRENT_URL2" "$RTORRENT_NAME" "--with-xmlrpc-c" ""
769}
770
771patchLibtorrent() {
772 # For gcc 4.6.0
773 ed -s "src/torrent/data/block_transfer.h" > /dev/null 2>&1 << EOF
774/#define LIBTORRENT_BLOCK_TRANSFER_H
775a
776#include <stddef.h>
777.
778w
779q
780EOF
781 ed -s "src/data/memory_chunk.cc" > /dev/null 2>&1 << EOF
782/#include "config.h"
783a
784#include <stddef.h>
785.
786w
787q
788EOF
789}
790
791installRtorrent() {
792 buildStart
793 buildRtorrent
794 buildEnd
795}
796
797installUnrar() {
798 isProgramInstalled unrar && return
799 installBuildTools
800 buildMakeProgram "$UNRAR_URL" "unrar" "" "unrar" "makefile.unix"
801}
802
803installModScgi() {
804 local modScgiFile="$1"
805 local modulesPath="$2"
806 [ -f "$modScgiFile" ] && errorExit "mod_scgi file already exists."
807 [ -d "$modulesPath" ] || errorExit "Apache modules path '$modulesPath' does not exist."
808
809 buildMakeProgram "$MOD_SCGI_URL" "mod_scgi" "apache2"
810 echo "LoadModule scgi_module $modulesPath/mod_scgi.so" > $modScgiFile
811}
812
813isPortUsed() {
814 local port="$1"
815 netstat -an | grep tcp | grep -w LISTEN | grep -qE "[.:]$port[ ]" && return 0
816 return 1
817}
818
819isValidIpAddress() {
820 # It's not 100% accurate ... ;)
821 echo $1 | grep -qE '^[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?$'
822}
823
824getIpAddress() {
825 isValidIpAddress "$OUR_IP_ADDRESS" && return
826 echo "${CMSG}Detecting your IP address...$CEND"
827 isValidIpAddress "$OUR_IP_ADDRESS" || OUR_IP_ADDRESS=$(wget --no-check-certificate http://www.whatismyip.com/automation/n09230945.asp -O - -o /dev/null)
828 isValidIpAddress "$OUR_IP_ADDRESS" || OUR_IP_ADDRESS=$(ifconfig -a | grep "inet addr" | head -n1 | awk -F: '{print $2}' | awk '{print $1}')
829 isValidIpAddress "$OUR_IP_ADDRESS" || OUR_IP_ADDRESS="1.2.3.4"
830}
831
832getNewPortNumber() {
833 while true; do
834 newPortNumber=$CURRENT_PORT
835 CURRENT_PORT=$(expr $CURRENT_PORT + 1)
836 isValidPortNumber $newPortNumber || errorExit "Invalid port number. Change CURRENT_PORT."
837 isPortUsed $newPortNumber || break
838 echo "${CWARNING}Port $newPortNumber is in use, trying next port...$CEND"
839 done
840}
841
842# Returns true if it's a valid ruTorrent base path
843isValidRutorrentBasePath() {
844 [ -n "$1" ] && [ -d "$1/conf" ]
845}
846
847isValidPassword() {
848 echo "$1" | grep -qE "^ " && return 1
849 echo "$1" | grep -qE " \$" && return 1
850 echo "$1" | grep -qE '^$' && return 1
851 echo "$1" | grep -q ':' && return 1
852 echo "'$1'" | grep -q ' ' && return 1
853 return 0
854}
855
856isValidPortNumber() {
857 echo "$1" | grep -qiE '^[0-9]+$' || return 1
858 echo "$1" | grep -qiE '[0-9][0-9][0-9][0-9][0-9][0-9]' && return 1
859 [ $1 -ge 1024 ] && [ $1 -le 65535 ]
860}
861
862isValidWebUser() {
863 [ -z "$1" ] && return 1
864 echo "$1" | LC_ALL=C grep -qE '[A-Z:]' && return 1
865 return 0
866}
867
868initUsers() {
869 local users=
870 for packedUser in $USERS; do
871 extractPackedUser $packedUser
872
873 if [ -z "$autodlPort" ]; then
874 getNewPortNumber
875 autodlPort=$newPortNumber
876 fi
877 if [ -z "$scgiPort" ]; then
878 getNewPortNumber
879 scgiPort=$newPortNumber
880 fi
881 if [ -z "$rtorrentPort" ]; then
882 getNewPortNumber
883 rtorrentPort=$newPortNumber
884 fi
885 if canGeneratePasswords; then
886 if [ -z "$autodlPassword" ]; then
887 generatePassword
888 autodlPassword="$newPassword"
889 fi
890 fi
891
892 users="$users $osUser:$autodlPassword:$webUser:$webPass:$autodlPort:$scgiPort:$rtorrentPort"
893 done
894 USERS="$users"
895}
896
897extractPackedUser() {
898 local packedUser="$1"
899
900 osUser="$(echo $packedUser | cut -d: -f1)"
901 autodlPassword="$(echo $packedUser | cut -d: -f2)"
902 webUser="$(echo $packedUser | cut -d: -f3)"
903 webPass="$(echo $packedUser | cut -d: -f4)"
904 autodlPort="$(echo $packedUser | cut -d: -f5)"
905 scgiPort="$(echo $packedUser | cut -d: -f6)"
906 rtorrentPort="$(echo $packedUser | cut -d: -f7)"
907}
908
909getUserGroup() {
910 local user="$1"
911
912 userExists "$user" || errorExit "The user '$user' does not exist."
913 group=$(grep -w $(id -rg $user) /etc/group | cut -d: -f1)
914 [ -z "$group" ] && group="$user"
915}
916
917getUserDir() {
918 local user="$1"
919
920 [ -z "$user" ] && errorExit "Invalid user (blank)."
921 userDir="$(eval echo ~$user)"
922 [ -d "$userDir" ] || errorExit "User $user's home directory does not exist."
923}
924
925resetOwner() {
926 local user="$1"
927 shift
928
929 if [ "$ISROOT" = y ]; then
930 getUserGroup "$user"
931 chown -R $user:$group "$@"
932 fi
933}
934
935# Updates MISSING_PHP_MODULES with all missing required PHP modules
936detectMissingPhpModules() {
937 MISSING_PHP_MODULES=
938 local php=${WWW_PHP_CGI:-php}
939 for module in $REQUIRED_PHP_MODULES; do
940 $php -m 2> /dev/null | grep -wq $module || MISSING_PHP_MODULES="$MISSING_PHP_MODULES $module"
941 done
942}
943
944installMissingPhpPackages() {
945 PACKAGES=
946 for module in $MISSING_PHP_MODULES; do
947 PACKAGES="$PACKAGES php-$module"
948 done
949 installPackages
950}
951
952#installMissingPhp5Packages() {
953# PACKAGES=
954# for module in $MISSING_PHP_MODULES; do
955# PACKAGES="$PACKAGES php5-$module"
956# done
957# installPackages
958#}
959
960enablePhpIniModules() {
961 local phpIni="$1"
962 shift
963 for module in "$@"; do
964 grep -qE "^extension=$module.so" "$phpIni" && continue
965 sed_i "s/^; *\\(extension=$module.so.*\\)/\\1/" "$phpIni"
966 grep -qE "^extension=$module.so" "$phpIni" && continue
967 echo "extension=$module.so" >> "$phpIni"
968 done
969}
970
971installMissingPhpModules() {
972 detectMissingPhpModules
973 [ -z "$MISSING_PHP_MODULES" ] && return
974
975 osHandler_$os installPhpModules
976
977 detectMissingPhpModules
978 [ -z "$MISSING_PHP_MODULES" ] && return
979 cat << EOF
980$CWARNING
981The following PHP modules appear to be missing:
982 $MISSING_PHP_MODULES
983If the autodl-irssi ruTorrent plugin isn't working, you now know why. Install
984them using your package manager or enable them in your php.ini file, and
985restart your web server.$CEND
986EOF
987}
988
989addLogrotateConfig() {
990 local serviceName="$1"
991 local logFiles="$2"
992 local postrotateScript="$3"
993
994 local logrotate_d=/etc/logrotate.d
995 [ -d "$logrotate_d" ] || errorExit "Missing logrotate dir: $logrotate_d"
996
997 cat > "$logrotate_d/$serviceName" << EOF
998$logFiles {
999 missingok
1000 daily
1001 rotate 14
1002 notifempty
1003 compress
1004 delaycompress
1005 sharedscripts
1006 postrotate
1007 $postrotateScript
1008 endscript
1009}
1010EOF
1011 [ $? -eq 0 ] || errorExit "Could not write logrotate file $logrotate_d/$serviceName"
1012}
1013
1014detectPhpCgi() {
1015 WWW_PHP_CGI=${WWW_PHP_CGI:-$(which php-cgi | head -n1)}
1016 [ -x "$WWW_PHP_CGI" ] || errorExit "Could not find php-cgi"
1017 "$WWW_PHP_CGI" -v | grep -q 'cgi-fcgi' || errorExit "$WWW_PHP_CGI does not support FastCGI"
1018}
1019
1020# $i is the i'th user number
1021getUserRpcMount() {
1022 local i=$1
1023 verifyWebServerVars
1024 # Make sure /RPC10 accesses aren't going to /RPC1 by padding with zeros. This is
1025 # easier than making sure every web server handles it correctly. Eg., lighttpd's
1026 # scgi.server table is read in order, so if you add /RPC1 before /RPC10, then
1027 # /RPC10 accesses will go to /RPC1. A fix would of course be to place /RPC10
1028 # before /RPC1 but it's easy to forget. Now we use /RPC00001 .. /RPC99999
1029 echo "/$RPC_PREFIX$(printf '%05d' $i)"
1030}
1031
1032createSelfSignedCertFile() {
1033 local pemfile="$1"
1034
1035 if [ ! -f "$OTHER_PEM_FILE" ]; then
1036 echo "${CMSG}Creating the self-signed certificate.$CEND"
1037 rm -f "$pemfile"
1038 openssl req -new -newkey rsa:1024 -days 1000 -nodes -x509 -keyout "$pemfile" -out "$pemfile" -batch \
1039 || errorExit "Failed to create self-signed certificate."
1040 OTHER_PEM_FILE="$pemfile"
1041 CREATED_CERT_FILE=y
1042 else
1043 rm -f "$pemfile"
1044 cp "$OTHER_PEM_FILE" "$pemfile" || errorExit "Failed to copy self-signed certificate."
1045 fi
1046
1047 chmod 0600 "$pemfile"
1048}
1049
1050detectHtpasswd() {
1051 [ -z "$htpasswd" ] && isProgramInstalled htpasswd && htpasswd=htpasswd
1052 [ -z "$htpasswd" ] && isProgramInstalled htpasswd2 && htpasswd=htpasswd2
1053 if [ -z "$htpasswd" ]; then
1054 installProgram python
1055 if isProgramInstalled python; then
1056 cd
1057 downloadFile "htpasswd.py" "$HTPASSWD_PY_SCRIPT_URL" "$HTPASSWD_PY_SCRIPT_URL2" \
1058 && htpasswd="python $(pwd)/htpasswd.py"
1059 fi
1060 fi
1061 [ -z "$htpasswd" ] && errorExit "Could not find htpasswd"
1062}
1063
1064verifyWebServerVars() {
1065 [ -z "$WWW_PEMFILE" ] && errorExit "You have not initialized WWW_PEMFILE"
1066 [ -z "$WWW_PASSWORD_FILE" ] && errorExit "You have not initialized WWW_PASSWORD_FILE"
1067 [ -z "$WWW_ROOT" ] && errorExit "You have not initialized WWW_ROOT"
1068 [ -z "$WWW_USER" ] && errorExit "You have not initialized WWW_USER"
1069 [ -z "$WWW_GROUP" ] && errorExit "You have not initialized WWW_GROUP"
1070}
1071
1072initializeWwwRootVar() {
1073 WWW_ROOT=${WWW_ROOT:-/var/rutorrent}
1074}
1075
1076createWebServerUserGroup() {
1077 verifyWebServerVars
1078 if ! grep -qE "^$WWW_GROUP:" /etc/group; then
1079 groupadd -r $WWW_GROUP 2>/dev/null || groupadd $WWW_GROUP || errorExit "Could not create web server group."
1080 fi
1081 if ! grep -qE "^$WWW_USER:" /etc/passwd; then
1082 local useradd="useradd -d $WWW_ROOT -g $WWW_GROUP -s /bin/sh"
1083 $useradd -M -r $WWW_USER 2>/dev/null || $useradd $WWW_USER || errorExit "Could not create web server user."
1084 fi
1085}
1086
1087resetAuthPasswordFilePermissions() {
1088 [ -n "$WWW_USER" ] || errorExit "WWW_USER not initialized"
1089 [ -n "$WWW_GROUP" ] || errorExit "WWW_GROUP not initialized"
1090 chmod 0400 "$WWW_PASSWORD_FILE"*
1091 chown $WWW_USER:$WWW_GROUP "$WWW_PASSWORD_FILE"*
1092}
1093
1094createAuthPasswordFile() {
1095 verifyWebServerVars
1096 : > "$WWW_PASSWORD_FILE"
1097 resetAuthPasswordFilePermissions
1098}
1099
1100# Some web servers (eg. nginx) can't allow just ONE user access to a certain
1101# location. To fix that, create one password file per user.
1102createOnePasswordFilePerUser() {
1103 for packedUser in $USERS; do
1104 extractPackedUser $packedUser
1105 grep "^$webUser:" "$WWW_PASSWORD_FILE" > "${WWW_PASSWORD_FILE}_$webUser"
1106 done
1107 resetAuthPasswordFilePermissions
1108}
1109
1110updatePhpTimezone() {
1111 if [ ! -f "$WWW_PHP_INI" ]; then
1112 echo "${CWARNING}Could not find php.ini file: $WWW_PHP_INI$CEND"
1113 return
1114 fi
1115 [ -z "$USER_TIMEZONE" ] && return
1116
1117 local zws="[ ]*"
1118 local newLine="date.timezone = $USER_TIMEZONE"
1119 if grep -qE "^${zws}date\\.timezone[ =]" "$WWW_PHP_INI"; then
1120 return
1121 elif grep -qE "^${zws}[;#]${zws}date\\.timezone[ =]" "$WWW_PHP_INI"; then
1122 sed_i "s!^${zws}[;#]${zws}date\\.timezone[ =].*\$!$newLine!" "$WWW_PHP_INI"
1123 else
1124 cat >> "$WWW_PHP_INI" << EOF
1125[Date]
1126$newLine
1127EOF
1128 fi
1129}
1130
1131doDetectTimeZone() {
1132 echo "${CMSG}Detecting timezone...$CEND"
1133 detectTimeZone
1134 if [ -n "$USER_TIMEZONE" ]; then
1135 echo "${CMSG}Timezone: $USER_TIMEZONE$CEND"
1136
1137 updatePhpTimezone
1138 else
1139 echo "${CWARNING}Could not detect timezone!$CEND"
1140 fi
1141}
1142
1143webServerCommonInitialization() {
1144 mkdir -p $WWW_ROOT
1145 doDetectTimeZone
1146 createSelfSignedCertFile "$WWW_PEMFILE"
1147 createAuthPasswordFile
1148}
1149
1150resetWebServerPermissions() {
1151 verifyWebServerVars
1152 chown -R $WWW_USER:$WWW_GROUP $WWW_ROOT || errorExit "Could not set web server as owner of $WWW_ROOT"
1153}
1154
1155createPhpcgiSocket() {
1156 PHPCGI_SOCKET_DIR=/etc/phpcgi
1157 PHPCGI_SOCKET_FILE="$PHPCGI_SOCKET_DIR/php-cgi.socket"
1158 mkdir -p "$PHPCGI_SOCKET_DIR"
1159 chown $WWW_USER:$WWW_GROUP "$PHPCGI_SOCKET_DIR"
1160 chmod 0770 "$PHPCGI_SOCKET_DIR"
1161}
1162
1163verifyApacheServerVars() {
1164 verifyWebServerVars
1165 [ -z "$APACHE_SITE_FILE" ] && errorExit "You have not initialized APACHE_SITE_FILE"
1166}
1167
1168apacheCreateApxs2Symlink() {
1169 # The makefile uses apxs2, so make a symlink
1170 if ! isProgramInstalled apxs2; then
1171 local apxs=$(which apxs 2>/dev/null) && ln -s "$apxs" "${apxs}2"
1172 fi
1173}
1174
1175initializeApacheVars() {
1176 local apacheUser="$1"
1177 local apacheGroup="$2"
1178 local apacheSitesDir="$3"
1179
1180 [ -n "$apacheUser" ] || errorExit "Invalid apache user: $apacheUser"
1181 [ -n "$apacheGroup" ] || errorExit "Invalid apache group: $apacheGroup"
1182 [ -d "$apacheSitesDir" ] || errorExit "Invalid apache sites dir: $apacheSitesDir"
1183 [ -d "$APACHE_DIR" ] || errorExit "Invalid apache dir: $APACHE_DIR"
1184
1185 APACHE_SITE_NAME=${APACHE_SITE_NAME:-rutorrent.conf}
1186 APACHE_SITE_FILE=$apacheSitesDir/$APACHE_SITE_NAME
1187 initializeWwwRootVar
1188 WWW_PASSWORD_FILE=$APACHE_DIR/rutorrent_passwd
1189 WWW_PEMFILE=$APACHE_DIR/rutorrent.pem
1190 WWW_USER="$apacheUser"
1191 WWW_GROUP="$apacheGroup"
1192}
1193
1194apacheGetRpcLocationDirectives() {
1195 if [ "$INSTALL_RUTORRENT" = y ]; then
1196 local i=1
1197 for packedUser in $USERS; do
1198 extractPackedUser $packedUser
1199 local rpcMount="$(getUserRpcMount $i)"
1200 cat << EOF
1201 <Location "$rpcMount">
1202 AuthType Basic
1203 AuthName "$RUTORRENT_SITE_REALM"
1204 AuthUserFile "$WWW_PASSWORD_FILE"
1205 Require user $webUser
1206 </Location>
1207EOF
1208 i=$(expr $i + 1)
1209 done
1210 fi
1211}
1212
1213apacheGetVirtualHost() {
1214 local port=$1
1215 local ssl=$2
1216 cat << EOF
1217<VirtualHost *:$port>
1218$(if [ "$ssl" = y ]; then
1219 echo " SSLEngine On"
1220 echo " SSLCertificateFile $WWW_PEMFILE"
1221fi)
1222 ServerAdmin admin@rutorrent
1223 ServerName localhost
1224 DocumentRoot $WWW_ROOT
1225
1226 <Directory />
1227 AllowOverride None
1228 Order deny,allow
1229 Deny from all
1230 </Directory>
1231 <Location />
1232 AuthType Basic
1233 AuthName "$RUTORRENT_SITE_REALM"
1234 AuthUserFile "$WWW_PASSWORD_FILE"
1235 Require valid-user
1236 Order allow,deny
1237 Allow from all
1238 </Location>
1239 <Location ~ "^/rutorrent/(conf|share)">
1240 Order deny,allow
1241 Deny from all
1242 </Location>
1243 <Location ~ "/\\\\.svn">
1244 Order deny,allow
1245 Deny from all
1246 </Location>
1247$(apacheGetRpcLocationDirectives)
1248</VirtualHost>
1249EOF
1250}
1251
1252apacheWriteSiteFile() {
1253 verifyApacheServerVars
1254 cat > "$APACHE_SITE_FILE" << EOF
1255ServerName localhost
1256
1257$(apacheGetVirtualHost $HTTP_PORT n)
1258$(apacheGetVirtualHost $HTTPS_PORT y)
1259EOF
1260
1261 if [ "$INSTALL_RUTORRENT" = y ]; then
1262 local i=1
1263 local lp=; isWebServerRpcModule || lp='#'
1264 for packedUser in $USERS; do
1265 extractPackedUser $packedUser
1266 local rpcMount="$(getUserRpcMount $i)"
1267 echo "${lp}SCGIMount $rpcMount $SCGI_HOST:$scgiPort" >> "$APACHE_SITE_FILE"
1268
1269 i=$(expr $i + 1)
1270 done
1271 fi
1272}
1273
1274apacheCommonInitialization() {
1275 local buildTools="$1"
1276 local modulesDir="$2"
1277
1278 webServerCommonInitialization
1279 apacheWriteSiteFile
1280
1281 if [ -n "$APACHE_SCGI_FILE" ] && [ ! -f "$APACHE_SCGI_FILE" ]; then
1282 installBuildTools
1283 PACKAGES="$buildTools"
1284 installPackages
1285 apacheCreateApxs2Symlink
1286
1287 # Compiling mod_scgi will fail unless we remove this warning-as-error flag
1288 local configVarsFile="$APACHE_DIR/modules/build/config_vars.mk"
1289 [ -f "$configVarsFile" ] && sed_i 's/-Werror=format-security//g' "$configVarsFile"
1290
1291 installModScgi "$APACHE_SCGI_FILE" "$modulesDir"
1292 fi
1293}
1294
1295nginxGetRpcMounts() {
1296 if [ "$INSTALL_RUTORRENT" = y ]; then
1297 local i=1
1298 local lp=; isWebServerRpcModule || lp='#'
1299 for packedUser in $USERS; do
1300 extractPackedUser $packedUser
1301 getUserScgiSocketPath "$osUser"
1302 local rpcMount="$(getUserRpcMount $i)"
1303
1304 cat << EOF
1305$lp location ~ ^$rpcMount\$ {
1306$lp include scgi_params;
1307$lp scgi_pass unix:$scgiSocketPath;
1308$lp auth_basic "$RUTORRENT_SITE_REALM";
1309$lp auth_basic_user_file "${WWW_PASSWORD_FILE}_$webUser";
1310$lp }
1311EOF
1312
1313 i=$(expr $i + 1)
1314 done
1315 fi
1316}
1317
1318nginxGetServerSection() {
1319 local port=$1
1320 local ssl=$2
1321
1322 cat << EOF
1323 server {
1324 listen $port;
1325 server_name localhost;
1326 auth_basic "$RUTORRENT_SITE_REALM";
1327 auth_basic_user_file "$WWW_PASSWORD_FILE";
1328
1329$(if [ "$ssl" = y ]; then
1330 cat << EOF2
1331 ssl on;
1332 ssl_certificate $WWW_PEMFILE;
1333 ssl_certificate_key $WWW_PEMFILE;
1334EOF2
1335fi)
1336
1337 location ~ ^/rutorrent/(?:share|conf) {
1338 deny all;
1339 }
1340
1341 location ~ /\.ht {
1342 deny all;
1343 }
1344
1345 location ~ /\.svn {
1346 deny all;
1347 }
1348
1349 location / {
1350 root $WWW_ROOT;
1351 index index.php index.html index.htm;
1352 }
1353
1354 location ~ \.php$ {
1355 root "$WWW_ROOT";
1356 fastcgi_pass unix:$PHPCGI_SOCKET_FILE;
1357 fastcgi_index index.php;
1358 fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
1359 include fastcgi_params;
1360 }
1361
1362$(nginxGetRpcMounts)
1363 }
1364EOF
1365}
1366
1367nginxWriteConfFile() {
1368 getNumCpus
1369 cat > $NGINX_CONF << EOF
1370worker_processes $NUMCPUS;
1371user $WWW_USER $WWW_GROUP;
1372events {
1373 worker_connections 1024;
1374}
1375
1376http {
1377 include mime.types;
1378 default_type application/octet-stream;
1379 sendfile on;
1380 keepalive_timeout 65;
1381
1382 # I have to set min length to 0 and http version to 1.0 or it won't compress
1383 # the XML-RPC (SCGI) responses. Those responses can be quite large if you're
1384 # using many torrent files.
1385 gzip on;
1386 gzip_min_length 0;
1387 gzip_http_version 1.0;
1388 gzip_types text/plain text/xml application/xml application/json text/css application/x-javascript text/javascript application/javascript;
1389
1390$(nginxGetServerSection $HTTP_PORT n)
1391$(nginxGetServerSection $HTTPS_PORT y)
1392}
1393EOF
1394 [ $? -eq 0 ] || errorExit "Could not write to file $NGINX_CONF"
1395}
1396
1397buildNginx() {
1398 buildStart
1399 PREFIX=$NGINX_DIR
1400 NGINX_BIN=$PREFIX/sbin/nginx
1401 NGINX_CONF=$PREFIX/conf/nginx.conf
1402 NGINX_PID_FILE=$PREFIX/nginx.pid
1403 NGINX_ACCESS_LOG=$PREFIX/logs/access.log
1404 NGINX_ERROR_LOG=$PREFIX/logs/error.log
1405 local configureFlags="\
1406 --prefix=$PREFIX \
1407 --sbin-path=$NGINX_BIN \
1408 --conf-path=$NGINX_CONF \
1409 --pid-path=$NGINX_PID_FILE \
1410 --lock-path=$PREFIX/logs/nginx.lock \
1411 --error-log-path=$NGINX_ERROR_LOG \
1412 --http-log-path=$NGINX_ACCESS_LOG \
1413 --user=$WWW_USER \
1414 --group=$WWW_GROUP \
1415 --with-http_ssl_module"
1416 export CFLAGS="$NGINX_CFLAGS"
1417 downloadAndBuild "nginx" "$NGINX_URL" "$NGINX_NAME" "$configureFlags" patchNginx
1418 unset CFLAGS
1419 buildEnd
1420}
1421
1422patchNginx() {
1423 # Get rid of the -Werror flag for gcc 4.6.0
1424 sed_i "s!-Werror[a-zA-Z0-9=-]*!!" "auto/cc/gcc"
1425}
1426
1427installNginx() {
1428 SCGI_USE_UNIX_DOMAIN_SOCKET=y
1429 CREATE_ONE_PASSWORD_FILE_PER_USER=y
1430 installBuildTools
1431 osHandler_$os preNginxInstall
1432 installUnrar
1433
1434 NGINX_DIR=/usr/local/nginx
1435 initializeWwwRootVar
1436 WWW_PASSWORD_FILE=$NGINX_DIR/rutorrent_passwd
1437 WWW_PEMFILE=$NGINX_DIR/rutorrent.pem
1438 WWW_USER=${WWW_USER:-nginx}
1439 WWW_GROUP=${WWW_GROUP:-nginx}
1440
1441 detectPhpCgi
1442 createWebServerUserGroup
1443 createPhpcgiSocket
1444
1445 buildNginx
1446 webServerCommonInitialization
1447 nginxWriteConfFile
1448
1449 addLogrotateConfig nginx \
1450 "$NGINX_ACCESS_LOG $NGINX_ERROR_LOG" \
1451 "[ -f \"$NGINX_PID_FILE\" ] && kill -USR1 \$(cat \"$NGINX_PID_FILE\") >/dev/null 2>&1; true"
1452
1453 resetWebServerPermissions
1454 osHandler_$os installPhpCgiService
1455 osHandler_$os installNginxService
1456}
1457
1458lighttpdGetRpcRequire() {
1459 if [ "$INSTALL_RUTORRENT" = y ]; then
1460 local i=1
1461 for packedUser in $USERS; do
1462 extractPackedUser $packedUser
1463 local rpcMount="$(getUserRpcMount $i)"
1464
1465 cat << EOF
1466 "$rpcMount" => (
1467 "method" => "basic",
1468 "realm" => "$RUTORRENT_SITE_REALM",
1469 "require" => "user=$webUser",
1470 ),
1471EOF
1472 i=$(expr $i + 1)
1473 done
1474 fi
1475}
1476
1477lighttpdGetScgiServerTable() {
1478 echo 'scgi.server = ('
1479
1480 if [ "$INSTALL_RUTORRENT" = y ]; then
1481 local i=1
1482 local lp=; isWebServerRpcModule || lp='#'
1483 for packedUser in $USERS; do
1484 extractPackedUser $packedUser
1485 getUserScgiSocketPath "$osUser"
1486 local rpcMount="$(getUserRpcMount $i)"
1487
1488 cat << EOF
1489$lp "$rpcMount" => (
1490$lp (
1491$lp "socket" => "$scgiSocketPath",
1492$lp "check-local" => "disable",
1493$lp "disable-time" => 0,
1494$lp ),
1495$lp ),
1496EOF
1497 i=$(expr $i + 1)
1498 done
1499 fi
1500
1501 echo ')'
1502}
1503
1504lighttpdWriteConfFile() {
1505 cat > $LIGHTTPD_CONF << EOF
1506server.follow-symlink = "disable"
1507server.max-connections = 512
1508server.max-fds = 1024
1509server.max-keep-alive-idle = 15
1510dir-listing.activate = "disable"
1511server.pid-file = "$LIGHTTPD_PID_FILE"
1512server.errorlog = "$LIGHTTPD_ERROR_LOG"
1513accesslog.filename = "$LIGHTTPD_ACCESS_LOG"
1514
1515$(if [ $(uname -s) = Linux ]; then
1516 echo 'server.event-handler = "linux-sysepoll"'
1517 echo 'server.network-backend = "linux-sendfile"'
1518fi)
1519
1520server.username = "$WWW_USER"
1521server.groupname = "$WWW_GROUP"
1522
1523server.modules = (
1524# "mod_rewrite",
1525# "mod_redirect",
1526# "mod_alias",
1527 "mod_access",
1528 "mod_auth",
1529# "mod_status",
1530# "mod_simple_vhost",
1531# "mod_evhost",
1532# "mod_userdir",
1533# "mod_secdownload",
1534 "mod_fastcgi",
1535# "mod_proxy",
1536# "mod_cgi",
1537 "mod_scgi",
1538# "mod_ssi",
1539# "mod_compress",
1540# "mod_usertrack",
1541# "mod_expire",
1542# "mod_rrdtool",
1543 "mod_accesslog",
1544)
1545
1546fastcgi.server = (
1547 ".php" => (
1548 (
1549 "socket" => "$PHPCGI_SOCKET_FILE",
1550 ),
1551 ),
1552)
1553
1554index-file.names = ( "index.php", "index.html", "index.htm" )
1555static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" )
1556
1557mimetype.assign = (
1558 ".html" => "text/html",
1559 ".htm" => "text/html",
1560 ".txt" => "text/plain",
1561 ".csv" => "text/plain",
1562 ".ini" => "text/plain",
1563 ".jpg" => "image/jpeg",
1564 ".jpeg" => "image/jpeg",
1565 ".gif" => "image/gif",
1566 ".png" => "image/png",
1567 ".bmp" => "image/bmp",
1568 ".css" => "text/css",
1569 ".js" => "application/javascript",
1570 ".ico" => "image/x-icon",
1571 ".json" => "application/json",
1572 ".torrent" => "application/x-bittorrent",
1573 ".pdf" => "application/pdf",
1574 ".bz2" => "application/x-bzip2",
1575 ".gz" => "application/x-gzip",
1576 ".tar.gz" => "application/x-tgz",
1577 ".tar" => "application/x-tar",
1578 ".tar.bz2" => "application/x-bzip-compressed-tar",
1579 ".tbz" => "application/x-bzip-compressed-tar",
1580 ".tgz" => "application/x-tgz",
1581 ".zip" => "application/zip",
1582 ".mp3" => "audio/mpeg",
1583 ".flac" => "audio/x-flac",
1584 ".m3u" => "audio/x-mpegurl",
1585 ".wma" => "audio/x-ms-wma",
1586 ".wax" => "audio/x-ms-wax",
1587 ".ogg" => "audio/ogg",
1588 ".wav" => "audio/x-wav",
1589 ".dtd" => "text/xml",
1590 ".xml" => "text/xml",
1591 ".mpeg" => "video/mpeg",
1592 ".mpg" => "video/mpeg",
1593 ".mp4" => "video/mp4",
1594 ".wmv" => "video/x-ms-wmv",
1595 ".avi" => "video/x-msvideo",
1596)
1597
1598server.document-root = "$WWW_ROOT"
1599server.port = $HTTP_PORT
1600
1601\$SERVER["socket"] == ":$HTTPS_PORT" {
1602 ssl.engine = "enable"
1603 ssl.pemfile = "$WWW_PEMFILE"
1604}
1605
1606url.access-deny = (".htaccess")
1607\$HTTP["url"] =~ "^/rutorrent/(?:share|conf)" {
1608 url.access-deny = ("")
1609}
1610\$HTTP["url"] =~ "/\\.svn" {
1611 url.access-deny = ("")
1612}
1613
1614auth.backend = "htpasswd"
1615auth.backend.htpasswd.userfile = "$WWW_PASSWORD_FILE"
1616auth.require = (
1617$(lighttpdGetRpcRequire)
1618 "/" => (
1619 "method" => "basic",
1620 "realm" => "$RUTORRENT_SITE_REALM",
1621 "require" => "valid-user",
1622 ),
1623)
1624
1625$(lighttpdGetScgiServerTable)
1626EOF
1627 [ $? -eq 0 ] || errorExit "Could not write to file $LIGHTTPD_CONF"
1628}
1629
1630buildLighttpd() {
1631 buildStart
1632 PREFIX=$LIGHTTPD_DIR
1633 LIGHTTPD_BIN=$PREFIX/sbin/lighttpd
1634 LIGHTTPD_CONF=$PREFIX/lighttpd.conf
1635
1636 # The log dir will be set to owner lighttpd since it's started as non-root.
1637 # Put the pid file there so it can write to it.
1638 LIGHTTPD_LOG_DIR=$PREFIX/logs
1639 LIGHTTPD_PID_FILE=$LIGHTTPD_LOG_DIR/lighttpd.pid
1640 LIGHTTPD_ERROR_LOG=$LIGHTTPD_LOG_DIR/error.log
1641 LIGHTTPD_ACCESS_LOG=$LIGHTTPD_LOG_DIR/access.log
1642
1643 local configureFlags="\
1644 --prefix=$PREFIX \
1645 --with-openssl \
1646 --with-pcre \
1647 --with-zlib \
1648 --without-bzip2"
1649 downloadAndBuild "lighttpd" "$LIGHTTPD_URL" "$LIGHTTPD_NAME" "$configureFlags"
1650 buildEnd
1651}
1652
1653installLighttpd() {
1654 SCGI_USE_UNIX_DOMAIN_SOCKET=y
1655 installBuildTools
1656 osHandler_$os preLighttpdInstall
1657 installUnrar
1658
1659 LIGHTTPD_DIR=/usr/local/lighttpd
1660 initializeWwwRootVar
1661 WWW_PASSWORD_FILE=$LIGHTTPD_DIR/rutorrent_passwd
1662 WWW_PEMFILE=$LIGHTTPD_DIR/rutorrent.pem
1663 WWW_USER=${WWW_USER:-lighttpd}
1664 WWW_GROUP=${WWW_GROUP:-lighttpd}
1665
1666 detectPhpCgi
1667 createWebServerUserGroup
1668 createPhpcgiSocket
1669
1670 buildLighttpd
1671 webServerCommonInitialization
1672 lighttpdWriteConfFile
1673
1674 addLogrotateConfig lighttpd \
1675 "$LIGHTTPD_ACCESS_LOG $LIGHTTPD_ERROR_LOG" \
1676 "[ -f \"$LIGHTTPD_PID_FILE\" ] && kill -HUP \$(cat \"$LIGHTTPD_PID_FILE\") >/dev/null 2>&1; true"
1677
1678 mkdir -p "$LIGHTTPD_LOG_DIR"
1679 chown -R $WWW_USER:$WWW_GROUP "$LIGHTTPD_LOG_DIR"
1680
1681 resetWebServerPermissions
1682 osHandler_$os installPhpCgiService
1683 osHandler_$os installLighttpdService
1684}
1685
1686# Add $name=$value to the file, or modify an existing line if present in the file
1687setVsftpdValue() {
1688 local confFile="$1"
1689 local name="$2"
1690 local value="$3"
1691 local newLine="$name=$value"
1692
1693 sed_i "s!^[ ]*$name[ =:].*\$!$newLine!" "$confFile"
1694 grep -qE "^$newLine$" "$confFile" || echo "$newLine" >> "$confFile"
1695}
1696
1697# Same as setVsftpdValue but makes sure the option exists
1698setVsftpdValue2() {
1699 local confFile="$1"
1700 local name="$2"
1701 local value="$3"
1702
1703 [ -z "$VSFTPD_PATH" ] && return
1704 grep -q "$name" "$VSFTPD_PATH" && setVsftpdValue "$confFile" "$name" "$value"
1705}
1706
1707updateVsftpdConf() {
1708 local confFile="$1"
1709 touch "$confFile"
1710
1711 VSFTPD_PATH=$(which vsftpd 2>/dev/null)
1712
1713 setVsftpdValue "$confFile" anonymous_enable NO
1714 setVsftpdValue "$confFile" dirlist_enable YES
1715 setVsftpdValue "$confFile" download_enable YES
1716 setVsftpdValue "$confFile" guest_enable NO
1717 setVsftpdValue "$confFile" listen YES
1718 setVsftpdValue "$confFile" listen_ipv6 NO
1719 setVsftpdValue "$confFile" local_enable YES
1720 setVsftpdValue "$confFile" local_umask $DEFAULT_UMASK
1721 setVsftpdValue "$confFile" max_per_ip 0
1722 setVsftpdValue "$confFile" pasv_enable YES
1723 setVsftpdValue "$confFile" port_enable YES
1724 setVsftpdValue "$confFile" pasv_promiscuous NO
1725 setVsftpdValue "$confFile" port_promiscuous NO
1726 setVsftpdValue "$confFile" pasv_min_port 0
1727 setVsftpdValue "$confFile" pasv_max_port 0
1728 setVsftpdValue "$confFile" write_enable YES
1729
1730 if [ "$USE_ENCRYPTED_FTP" = y ]; then
1731 local pemfile=/etc/vsftpd.pem
1732 createSelfSignedCertFile "$pemfile"
1733
1734 FTP_SERVER_TYPE="FTPES - Encrypted (FTP over explicit TLS/SSL)"
1735 FTP_PORT=${FTP_PORT:-$DEFAULT_PORT_FTPES}
1736 setVsftpdValue "$confFile" listen_port $FTP_PORT
1737 setVsftpdValue "$confFile" ssl_enable YES
1738
1739 setVsftpdValue "$confFile" allow_anon_ssl NO
1740 setVsftpdValue "$confFile" force_local_data_ssl YES
1741 setVsftpdValue "$confFile" force_local_logins_ssl YES
1742 setVsftpdValue "$confFile" ssl_sslv2 NO
1743 setVsftpdValue "$confFile" ssl_sslv3 NO
1744 setVsftpdValue "$confFile" ssl_tlsv1 YES
1745 setVsftpdValue "$confFile" rsa_cert_file "$pemfile"
1746
1747 setVsftpdValue2 "$confFile" implicit_ssl NO
1748 setVsftpdValue2 "$confFile" require_cert NO
1749 setVsftpdValue2 "$confFile" require_ssl_reuse NO
1750 setVsftpdValue2 "$confFile" ssl_request_cert YES
1751 setVsftpdValue2 "$confFile" strict_ssl_read_eof NO
1752 setVsftpdValue2 "$confFile" strict_ssl_write_shutdown NO
1753 setVsftpdValue2 "$confFile" validate_cert NO
1754 else
1755 FTP_SERVER_TYPE="FTP - Non-encrypted"
1756 FTP_PORT=${FTP_PORT:-$DEFAULT_PORT_FTP}
1757 setVsftpdValue "$confFile" listen_port $FTP_PORT
1758 setVsftpdValue "$confFile" ssl_enable NO
1759 fi
1760
1761 # The private key is in rsa_cert_file
1762 sed_i 'g/rsa_private_key_file/d' "$confFile"
1763}
1764
1765installVsftpd_chkconfig() {
1766 local vsftpdConf="$1"
1767 installProgram vsftpd
1768 [ -f "$vsftpdConf" ] || errorExit "Invalid vsftpd.conf file: $vsftpdConf"
1769 updateVsftpdConf "$vsftpdConf"
1770 chkconfig vsftpd on
1771 if ! service vsftpd restart; then
1772 if [ "$SELINUX_ENABLED" = y ]; then
1773 errorExit "Could not restart vsftpd. SELinux could be the reason."
1774 else
1775 errorExit "Could not restart vsftpd"
1776 fi
1777 fi
1778}
1779
1780installService_chkconfig1() {
1781 CHKCONFIG_SERVICE_NAME=$1
1782 CHKCONFIG_SERVICE_FILE=/etc/init.d/$CHKCONFIG_SERVICE_NAME
1783 CHKCONFIG_LOCK_FILE=/var/lock/subsys/$CHKCONFIG_SERVICE_NAME
1784}
1785
1786installService_chkconfig2() {
1787 chmod +x "$CHKCONFIG_SERVICE_FILE" || errorExit "Could not set +x bit, file $CHKCONFIG_SERVICE_FILE."
1788 chkconfig --add $CHKCONFIG_SERVICE_NAME || errorExit "Could not install service $CHKCONFIG_SERVICE_FILE. Run this script as root."
1789 service $CHKCONFIG_SERVICE_NAME restart
1790}
1791
1792getChkconfigScriptContents() {
1793 local desc="$1"
1794 cat << EOF
1795# chkconfig: 2345 85 15
1796# description: $desc
1797EOF
1798}
1799
1800getLsbStartupScriptContents() {
1801 local startupName="$1"
1802 local desc="$2"
1803 cat << EOF
1804### BEGIN INIT INFO
1805# Provides: $startupName
1806# Required-Start: \$local_fs \$network \$syslog
1807# Required-Stop: \$local_fs \$syslog
1808# Default-Start: $LSB_DEFAULT_START
1809# Default-Stop: $LSB_DEFAULT_STOP
1810# Short-Description: $desc
1811# Description: $desc
1812### END INIT INFO
1813EOF
1814}
1815
1816# You must define v_{startIt,stopIt,restartIt,showStatus} and isStarted funcs
1817getLsbStartupFooter() {
1818 cat << EOF
1819resetPath # Some include files may have reset it
1820LOCKFILE=$1
1821updateLock() {
1822 [ -z "\$LOCKFILE" ] && return
1823 if isStarted; then
1824 touch \$LOCKFILE
1825 else
1826 rm -f \$LOCKFILE
1827 fi
1828}
1829
1830RETVAL=0
1831case \$1 in
1832 start)
1833 v_startIt
1834 ;;
1835 stop)
1836 v_stopIt
1837 ;;
1838 force-reload|restart)
1839 v_restartIt
1840 ;;
1841 try-restart)
1842 isStarted && v_restartIt
1843 ;;
1844 status)
1845 v_showStatus
1846 ;;
1847 *)
1848 echo "Usage: \$0 {start|stop|restart|try-restart|force-reload|status}"
1849 RETVAL=1
1850 ;;
1851esac
1852
1853updateLock
1854exit \$RETVAL
1855EOF
1856}
1857
1858getCommonStartupScriptContents_autodl() {
1859 local USER="$1"
1860 local STARTUPNAME="$2"
1861 cat << EOF
1862NAME=$STARTUPNAME
1863USER=$USER
1864SESSIONNAME=autodl
1865
1866resetPath() {
1867 PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:\$PATH"
1868}
1869resetPath
1870
1871# Make sure the path is correct, and make sure we're in the home dir.
1872USER_INIT="umask $DEFAULT_UMASK; cd; PATH=\\\$PATH:\$PATH"
1873
1874# Run user command, ignoring any messages sent to stdout (eg. 'No mail.')
1875runUserCmd() {
1876 su - \$USER -c "\$USER_INIT; \$1" >/dev/null && return 0
1877 return 1
1878}
1879
1880isStarted() {
1881 su - \$USER -c "\$USER_INIT; screen -ls | grep -qE \\"[ ][0-9]+\\\\.\$SESSIONNAME[ ]\\"" >/dev/null && return 0
1882 return 1
1883}
1884
1885startIt() {
1886 isStarted && return 0
1887
1888 local START_IRSSI=n
1889 local START_RTORRENT=n
1890 which irssi > /dev/null 2>&1 && START_IRSSI=y
1891 which rtorrent > /dev/null 2>&1 && START_RTORRENT=y
1892
1893 case \$START_IRSSI\$START_RTORRENT in
1894 yy)
1895 runUserCmd "screen -S \$SESSIONNAME -d -t rtorrent -m rtorrent"
1896 runUserCmd "screen -d -r \$SESSIONNAME -X screen -t irssi irssi"
1897 ;;
1898 yn)
1899 runUserCmd "screen -S \$SESSIONNAME -d -t irssi -m irssi"
1900 ;;
1901 ny)
1902 runUserCmd "screen -S \$SESSIONNAME -d -t rtorrent -m rtorrent"
1903 ;;
1904 nn)
1905 ;;
1906 esac
1907 return 0
1908}
1909
1910stopIt() {
1911 isStarted || return 0
1912
1913 runUserCmd "screen -d -r \$SESSIONNAME -p irssi -X stuff \\"/quit
1914/quit
1915\\""
1916 runUserCmd "screen -d -r \$SESSIONNAME -p rtorrent -X xon"
1917
1918 for i in 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4; do
1919 isStarted || break
1920 sleep 1
1921 done
1922
1923 # If it's still not stopped, kill the whole screen session
1924 if isStarted; then
1925 echo -n "Couldn't stop it. Killing screen session..."
1926 runUserCmd "screen -d -r \$SESSIONNAME -p rtorrent -X xon"
1927 sleep 2
1928 runUserCmd "screen -d -r \$SESSIONNAME -X quit"
1929 echo "Done."
1930 fi
1931
1932 return 0
1933}
1934
1935v_restartIt() {
1936 v_stopIt
1937 v_startIt
1938}
1939
1940v_showStatus() {
1941 if isStarted; then
1942 echo "\$NAME is running."
1943 else
1944 echo "\$NAME is stopped."
1945 fi
1946}
1947EOF
1948}
1949
1950getChkconfigScriptContents_autodl() {
1951 getChkconfigScriptContents "$AUTODL_STARTUP_DESC"
1952}
1953
1954# LSB style script, also supports chkconfig
1955# $1 = user name
1956# $2 = service name
1957getLsbStartupHeader_autodl() {
1958 local USER="$1"
1959 local STARTUPNAME="$2"
1960 cat << EOF
1961$(getChkconfigScriptContents_autodl)
1962$(getLsbStartupScriptContents "$STARTUPNAME" "$AUTODL_STARTUP_DESC")
1963
1964$(getCommonStartupScriptContents_autodl "$USER" "$STARTUPNAME")
1965EOF
1966}
1967
1968installService_bsd_autodl() {
1969 local user="$1"
1970 local scriptName="$2"
1971 local file="$3"
1972
1973 cat > "$file" << EOF
1974#!/bin/sh
1975# PROVIDE: autodl_$user
1976# REQUIRE: FILESYSTEMS NETWORKING
1977# KEYWORD: shutdown
1978
1979. /etc/rc.subr
1980
1981name=$scriptName
1982desc="$AUTODL_STARTUP_DESC"
1983start_cmd=v_startIt
1984stop_cmd=v_stopIt
1985restart_cmd=v_restartIt
1986reload_cmd=v_restartIt
1987status_cmd=v_showStatus
1988extra_commands="status"
1989
1990v_startIt() {
1991 echo -n "Starting \$NAME"
1992 startIt && echo "." || echo ". ERROR."
1993}
1994
1995v_stopIt() {
1996 echo -n "Stopping \$NAME..."
1997 stopIt && echo "done." || echo "ERROR."
1998}
1999
2000$(getCommonStartupScriptContents_autodl "$user" "$scriptName")
2001
2002load_rc_config \$name
2003run_rc_command "\$1"
2004EOF
2005 [ $? -eq 0 ] || errorExit "Could not write to file $file. Run this script as root."
2006 chmod +x "$file"
2007}
2008
2009getCommonStartupScriptContents_simpleService() {
2010 local USER="$1"
2011 local BINPATH="$2"
2012 local START_CMD="$3"
2013 local PID_FILE="$4"
2014 cat << EOF
2015USER=$USER
2016BINPATH="$BINPATH"
2017NAME=\${BINPATH##*/}
2018PID_FILE="$PID_FILE"
2019
2020resetPath() {
2021 PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:\$PATH"
2022}
2023resetPath
2024
2025getPids() {
2026 if [ -n "\$PID_FILE" ]; then
2027 pids=
2028 [ -f "\$PID_FILE" ] || return
2029 local the_pids="\$(cat "\$PID_FILE" 2>/dev/null)"
2030 for pid in \$the_pids; do
2031 PS_FORMAT= LINES= COLUMNS= ps ax | grep -qE "^[ ]*\$pid[ ]" && pids="\$pids \$pid"
2032 done
2033 [ -z "\$pids" ] && rm -f "\$PID_FILE"
2034 else
2035 # ps uses the COLUMNS variable... Make sure it's off so we get the full path.
2036 pids=\$(PS_FORMAT= LINES= COLUMNS= ps aux | grep -v grep | grep \$BINPATH | awk '{print \$2}')
2037 fi
2038}
2039
2040isStarted() {
2041 getPids
2042 [ -n "\$pids" ] && return 0
2043 return 1
2044}
2045
2046startIt() {
2047 isStarted && return 0
2048
2049 if [ \$USER = root ]; then
2050 $START_CMD
2051 else
2052 su - \$USER "-c $START_CMD"
2053 fi
2054 [ -n "\$PID_FILE" ] && sleep 2 # Allow it some time to create the pid file
2055 if ! isStarted; then
2056 for i in 1 2 3 4 5; do
2057 sleep 1
2058 isStarted && break
2059 done
2060 isStarted || return 1
2061 fi
2062
2063 return 0
2064}
2065
2066stopIt() {
2067 isStarted || return 0
2068
2069 kill \$pids 2>/dev/null
2070
2071 for i in 0 1 2 3 4 5 6 7 8 9; do
2072 isStarted || break
2073 sleep 1
2074 done
2075
2076 isStarted && kill -KILL \$pids 2>/dev/null
2077
2078 return 0
2079}
2080
2081v_startIt() {
2082 startIt
2083}
2084
2085v_stopIt() {
2086 stopIt
2087}
2088
2089v_restartIt() {
2090 v_stopIt
2091 v_startIt
2092}
2093
2094v_showStatus() {
2095 if isStarted; then
2096 echo "\$NAME is running."
2097 else
2098 echo "\$NAME is stopped."
2099 fi
2100}
2101EOF
2102}
2103
2104getCommonStartupScriptContents_phpcgi() {
2105 [ -n "$PHPCGI_SOCKET_FILE" ] || errorExit "PHPCGI_SOCKET_FILE is not initialized"
2106 getCommonStartupScriptContents_simpleService "$1" "$2" \
2107 "PHP_FCGI_CHILDREN=5 PHP_FCGI_MAX_REQUESTS=125 \$BINPATH -q -b \"$PHPCGI_SOCKET_FILE\" &"
2108}
2109
2110getLsbStartupHeader_phpcgi() {
2111 getChkconfigScriptContents "$PHPCGI_STARTUP_DESC"
2112 getLsbStartupScriptContents phpcgi "$PHPCGI_STARTUP_DESC"
2113
2114 getCommonStartupScriptContents_phpcgi "$WWW_USER" "$WWW_PHP_CGI"
2115}
2116
2117getCommonStartupScriptContents_nginx() {
2118 getCommonStartupScriptContents_simpleService "root" "$1" "\$BINPATH" "$NGINX_PID_FILE"
2119}
2120
2121getLsbStartupHeader_nginx() {
2122 getChkconfigScriptContents "$NGINX_STARTUP_DESC"
2123 getLsbStartupScriptContents nginx "$NGINX_STARTUP_DESC"
2124
2125 getCommonStartupScriptContents_nginx "$NGINX_BIN"
2126}
2127
2128getCommonStartupScriptContents_lighttpd() {
2129 getCommonStartupScriptContents_simpleService "root" "$1" "\$BINPATH -f $LIGHTTPD_CONF 2>/dev/null" "$LIGHTTPD_PID_FILE"
2130}
2131
2132getLsbStartupHeader_lighttpd() {
2133 getChkconfigScriptContents "$LIGHTTPD_STARTUP_DESC"
2134 getLsbStartupScriptContents lighttpd "$LIGHTTPD_STARTUP_DESC"
2135
2136 getCommonStartupScriptContents_lighttpd "$LIGHTTPD_BIN"
2137}
2138
2139addLsbHeaderToStartupScript() {
2140 local scriptPath="$1"
2141 local provides="${2:-$scriptPath}"
2142 local desc="${3:-$provides}"
2143 [ -x "$scriptPath" ] || return
2144 grep -qE '^### BEGIN INIT INFO' "$scriptPath" && return
2145 ed -s "$scriptPath" > /dev/null 2>&1 << EOF
21461a
2147$(getLsbStartupScriptContents "$provides" "$desc")
2148.
2149w
2150q
2151EOF
2152}
2153
2154installMissingPerlModules() {
2155 detectMissingPerlModules
2156 [ -z "$MISSING_PERL_MODULES" ] && return
2157 cat << EOF
2158$CWARNING
2159The following Perl modules are still missing:
2160 $MISSING_PERL_MODULES
2161I'll try to use the cpan script to install them.$CEND
2162EOF
2163
2164 # Some Perl modules will fail to build unless Test::More is installed
2165 MISSING_PERL_MODULES="Test::More $MISSING_PERL_MODULES"
2166
2167 echo "${CMSG}Installing cpan and required build tools...$CEND"
2168 installBuildTools
2169 osHandler_$os installCpanTools
2170 detectCpanBin
2171 if [ -n "$CPAN" ]; then
2172 $CPAN $MISSING_PERL_MODULES
2173 else
2174 local mods=
2175 for mod in $MISSING_PERL_MODULES; do
2176 [ -n "$mods" ] && mods="$mods,"
2177 mods="$mods \"$mod\""
2178 done
2179 perl -MCPAN -e "CPAN::Shell->install($mods)"
2180 fi
2181
2182 detectMissingPerlModules
2183 [ -z "$MISSING_PERL_MODULES" ] && return
2184 errorExit "CPAN somehow failed to install the missing Perl modules. Missing: $MISSING_PERL_MODULES"
2185}
2186
2187osHandler_debian() {
2188 case $1 in
2189 init)
2190 INSTALL="apt-get -y install"
2191 FEATURES="service rtorrent apache nginx lighttpd vsftpd webmin"
2192 BUILD_TOOLS="build-essential make file pkg-config libtool m4"
2193 ;;
2194 init2)
2195 apt-get update
2196 installProgram ed
2197
2198 # Make sure Debian 6 doesn't fail when adding new services. We need ed for this
2199 # so run it after installing ed...
2200 addLsbHeaderToStartupScript /etc/init.d/webmin "webmin" "webmin"
2201 ;;
2202 installTools)
2203 PACKAGES=
2204 addProgram irssi
2205 addProgram mediainfo
2206 addProgram git-core
2207 addProgram svn subversion
2208 addProgram wget
2209 addProgram unzip
2210 addProgram screen
2211 installPackages
2212 # Make sure subversion won't complain about invalid certs
2213 $INSTALL ca-certificates
2214 ;;
2215 installAutodlTools)
2216 PACKAGES=
2217 addProgram perl
2218 addPerlModule Archive::Zip libarchive-zip-perl
2219 addPerlModule HTML::Parser libhtml-parser-perl
2220 addPerlModule Digest::SHA libdigest-sha-perl
2221 installPackages
2222
2223 installPerlModule Net::SSLeay libnet-ssleay-perl
2224 installPerlModule XML::LibXML libxml-libxml-perl
2225 installPerlModule JSON::XS libjson-xs-perl
2226 installPerlModule JSON libjson-perl
2227 ;;
2228 installCpanTools)
2229 # Need to remove the old JSON or cpan may fail to build the modules
2230 if echo "$OLD_PERL_MODULES" | grep -qE '(^| )JSON( |$)'; then
2231 apt-get -y remove libjson-perl
2232 fi
2233
2234 PACKAGES=
2235 if echo "$MISSING_PERL_MODULES" | grep -q 'XML::LibXML'; then
2236 PACKAGES="$PACKAGES libxml2 libxml2-dev zlib1g zlib1g-dev"
2237 fi
2238 if echo "$MISSING_PERL_MODULES" | grep -q 'Net::SSLeay'; then
2239 # There's no libssl package
2240 PACKAGES="$PACKAGES openssl libssl-dev zlib1g zlib1g-dev"
2241 fi
2242 installPackages
2243 ;;
2244 installRtorrentBuildTools)
2245 PACKAGES="libsigc++-2.0-dev libssl-dev libncurses-dev"
2246 if apt-cache search libcurl4-openssl-dev 2> /dev/null | grep -q 'libcurl4-openssl-dev'; then
2247 PACKAGES="$PACKAGES libcurl4-openssl-dev"
2248 else
2249 PACKAGES="$PACKAGES libcurl3-openssl-dev"
2250 fi
2251 installPackages
2252 ;;
2253 installPhpModules)
2254 installMissingPhpPackages
2255 ;;
2256 _installService)
2257 local serviceName="$2"
2258 local headerCommand="$3"
2259 local serviceFile=/etc/init.d/$serviceName
2260 local lockFile=
2261 cat > "$serviceFile" << EOF
2262#!/bin/sh
2263$(eval $headerCommand)
2264
2265. /lib/lsb/init-functions
2266
2267v_startIt() {
2268 log_begin_msg "Starting \$NAME..."
2269 startIt
2270 log_end_msg \$?
2271}
2272
2273v_stopIt() {
2274 log_begin_msg "Stopping \$NAME..."
2275 stopIt
2276 log_end_msg \$?
2277}
2278
2279$(getLsbStartupFooter "$lockFile")
2280EOF
2281 [ $? -eq 0 ] || errorExit "Could not write to file $serviceFile. Run this script as root."
2282 chmod +x "$serviceFile" || errorExit "Could not set +x bit, file $serviceFile."
2283 update-rc.d $serviceName defaults || errorExit "Could not install service $serviceFile. Run this script as root."
2284 invoke-rc.d $serviceName restart
2285 ;;
2286 installAutodlService)
2287 local user=$2
2288 osHandler_$os _installService autodl_$user "getLsbStartupHeader_autodl \"$user\" \"\$serviceName\""
2289 ;;
2290 _installCommonWebServerStuff)
2291 # Also add some extra tools for ruTorrent and some of its plugins
2292 PACKAGES="php7.0-cli gzip curl openssl logrotate"
2293 installPackages
2294 # Ubuntu 8 doesn't have php5-geoip
2295 PACKAGES="php-geoip"
2296 installPackages
2297 PACKAGES="unrar"
2298 installPackages
2299 ;;
2300 installApache)
2301 osHandler_$os _installCommonWebServerStuff
2302 PACKAGES="libapache2-mpm-itk libapache2-mod-php php apache2"
2303 installPackages
2304 PACKAGES="libapache2-mod-scgi"; installPackages
2305
2306 WWW_PHP_INI=/etc/php/7.0/apache2/php.ini
2307 APACHE_DIR=/etc/apache2
2308 APACHE_SITE_NAME=rutorrent.conf
2309 APACHE_SCGI_FILE=$APACHE_DIR/mods-available/scgi.load
2310 initializeApacheVars www-data www-data "$APACHE_DIR/sites-available"
2311 apacheCommonInitialization "apache2-prefork-dev" /usr/lib/apache2/modules
2312
2313 a2enmod ssl || errorExit "Could not enable mod_ssl"
2314 a2enmod scgi || errorExit "Could not enable mod_scgi"
2315 # Ubuntu Server 6 doesn't come with this module
2316 a2enmod auth_basic
2317 a2dissite default
2318 a2dissite default-ssl
2319 a2ensite $APACHE_SITE_NAME || errorExit "Could not enable site"
2320 if ! grep -qE "^[ ]*Listen.*[: ]$HTTPS_PORT\\>" "$APACHE_DIR/ports.conf"; then
2321 echo "Listen $HTTPS_PORT" >> "$APACHE_DIR/ports.conf"
2322 fi
2323 resetWebServerPermissions
2324 invoke-rc.d apache2 restart || errorExit "Could not start $INSTALL_WEB_SERVER"
2325 ;;
2326 restart_apache)
2327 invoke-rc.d apache2 restart || errorExit "Could not start $INSTALL_WEB_SERVER"
2328 ;;
2329 installVsftpd)
2330 installProgram vsftpd
2331 updateVsftpdConf /etc/vsftpd.conf
2332 invoke-rc.d vsftpd restart || errorExit "Could not restart vsftpd"
2333 ;;
2334 preNginxInstall)
2335 WWW_PHP_INI=/etc/php5/cgi/php.ini
2336 osHandler_$os _installCommonWebServerStuff
2337 PACKAGES="libpcre3-dev libssl-dev zlib1g-dev php7.0-cgi"
2338 installPackages
2339
2340 # Make sure it builds on Debian GNU/kFreeBSD 6.0.
2341 if [ "$(uname -s)" != Linux ]; then
2342 NGINX_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
2343 fi
2344 ;;
2345 installPhpCgiService)
2346 osHandler_$os _installService phpcgi getLsbStartupHeader_phpcgi
2347 ;;
2348 installNginxService)
2349 osHandler_$os _installService nginx getLsbStartupHeader_nginx
2350 ;;
2351 restart_nginx)
2352 invoke-rc.d phpcgi restart || errorExit "Could not start php-cgi"
2353 invoke-rc.d nginx restart || errorExit "Could not start $INSTALL_WEB_SERVER"
2354 ;;
2355 preLighttpdInstall)
2356 WWW_PHP_INI=/etc/php5/cgi/php.ini
2357 osHandler_$os _installCommonWebServerStuff
2358 PACKAGES="libpcre3-dev libssl-dev zlib1g-dev php7.0-cgi"
2359 installPackages
2360 ;;
2361 installLighttpdService)
2362 osHandler_$os _installService lighttpd getLsbStartupHeader_lighttpd
2363 ;;
2364 restart_lighttpd)
2365 invoke-rc.d phpcgi restart || errorExit "Could not start php-cgi"
2366 invoke-rc.d lighttpd restart || errorExit "Could not start $INSTALL_WEB_SERVER"
2367 ;;
2368 postWebminInstall)
2369 addLsbHeaderToStartupScript /etc/init.d/webmin "webmin" "webmin"
2370 ;;
2371 *)
2372 ;;
2373 esac
2374}
2375
2376isWebServerRpcModule() {
2377 ! arrayIsPresent rpc $RUTORRENT_PLUGINS && ! arrayIsPresent httprpc $RUTORRENT_PLUGINS && return 0
2378 return 1
2379}
2380
2381canInstallService() {
2382 return $(arrayIsPresent service $FEATURES)
2383}
2384
2385canInstallRtorrent() {
2386 return $(arrayIsPresent rtorrent $FEATURES)
2387}
2388
2389canInstallApache() {
2390 return $(arrayIsPresent apache $FEATURES)
2391}
2392
2393canInstallNginx() {
2394 return $(arrayIsPresent nginx $FEATURES)
2395}
2396
2397canInstallLighttpd() {
2398 return $(arrayIsPresent lighttpd $FEATURES)
2399}
2400
2401canInstallVsftpd() {
2402 return $(arrayIsPresent vsftpd $FEATURES)
2403}
2404
2405canInstallWebmin() {
2406 return $(arrayIsPresent webmin $FEATURES)
2407}
2408
2409getRequiredPrograms() {
2410 REQUIRED_PROGRAMS="which svn wget unzip ed sed grep tar expr ps awk kill printf"
2411
2412 if [ "$INSTALL_AUTODL_IRSSI" = y ]; then
2413 REQUIRED_PROGRAMS="$REQUIRED_PROGRAMS perl"
2414
2415 # NetBSD and DragonFly BSD don't compile Irssi with Perl support by default
2416 [ "$IGNORE_IRSSI" != y ] && REQUIRED_PROGRAMS="$REQUIRED_PROGRAMS irssi"
2417 fi
2418}
2419
2420verifyInstalledPrograms() {
2421 getRequiredPrograms
2422
2423 local MISSING_PROGRAMS=
2424 for prog in $REQUIRED_PROGRAMS; do
2425 local name=$prog
2426 [ "$prog" = svn ] && name=subversion
2427 isProgramInstalled "$prog" || MISSING_PROGRAMS="$MISSING_PROGRAMS $name"
2428 done
2429 [ -n "$MISSING_PROGRAMS" ] && errorExit "Can't continue. The following programs are not installed: $MISSING_PROGRAMS"
2430}
2431
2432initPluginDirVar() {
2433 AUTODL_IRSSI_PLUGIN_DIR="$RUTORRENT_BASE_PATH/plugins/autodl-irssi"
2434}
2435
2436getRtorrentDirs() {
2437 local user="$1"
2438 getUserDir "$user"
2439 RTORRENT_DOWNLOAD_DIR="$userDir/$RTORRENT_REL_DOWNLOAD_DIR"
2440 RTORRENT_WATCH_DIR="$userDir/$RTORRENT_REL_WATCH_DIR"
2441 RTORRENT_SESSION_DIR="$userDir/$RTORRENT_REL_SESSION_DIR"
2442}
2443
2444getUserScgiSocketPath() {
2445 local user="$1"
2446 getRtorrentDirs "$user"
2447 scgiSocketPath="$RTORRENT_SESSION_DIR/rpc.socket"
2448}
2449
2450waitenter() {
2451 local msg="${1-Press ENTER to continue...}"
2452 echo -n "$CCYAN$msg$CEND"
2453 read dummy
2454}
2455
2456askQuestion() {
2457 local question="$1"
2458 local default="$2"
2459
2460 if [ -z "$default" ]; then
2461 echo -n "$CQUESTION$question$CEND "
2462 read answer
2463 else
2464 echo -n "$CQUESTION$question$CEND [$CGREEN$default$CEND] "
2465 read answer
2466 fi
2467 if [ -z "$answer" ]; then
2468 answer="$default"
2469 fi
2470}
2471
2472# Asks the user a question, and sets answer to y or n depending on the user's answer
2473askYesNo() {
2474 local question="$1"
2475 local default="$2"
2476
2477 while true; do
2478 askQuestion "$question" "$default"
2479 if echo "$answer" | grep -qiE '^y(es)?$'; then
2480 answer=y
2481 return 1
2482 elif echo "$answer" | grep -qiE '^no?$'; then
2483 answer=n
2484 return 0
2485 fi
2486 done
2487}
2488
2489askOsUser() {
2490 local stopIfEmpty=${1:-n}
2491 local user=
2492 while true; do
2493 askQuestion "Enter name of user:" ""
2494 user="$answer"
2495 [ -z "$user" ] && [ "$stopIfEmpty" = y ] && break
2496 userExists "$user" && break
2497
2498 echo "${CWARNING}User $user does not exist.$CEND"
2499 askYesNo "Do you want to create user $user?" "No"
2500 [ "$answer" = n ] && continue
2501
2502 echo "${CMSG}Creating user $user.$CEND"
2503 if ! useradd -m -s /bin/sh "$user"; then
2504 echo "${CWARNING}Could not create user $user.$CEND"
2505 continue
2506 fi
2507 echo "${CMSG}Enter the user's password:$CEND"
2508 if ! passwd "$user"; then
2509 echo "${CWARNING}Failed to set password.$CEND"
2510 continue
2511 fi
2512 userExists "$user" && break
2513 done
2514 answer="$user"
2515}
2516
2517# Adds another user to USERS
2518addUser() {
2519 local osUser="$1"
2520 local webUser="$2"
2521 local autodlPassword=
2522 local webpass=
2523
2524 if [ "$INSTALL_RUTORRENT" = y ] || [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2525 if ! canGeneratePasswords; then
2526 cat << EOF
2527$CQUESTION
2528The password makes sure only you can change your autodl-irssi settings. This is
2529NOT your login password. Use any password, but each user should use a unique
2530password. The password is used by the PHP code to access autodl-irssi settings.
2531You don't need to remember this password. It can't contain any spaces or a
2532colon ':'.$CEND
2533EOF
2534 while true; do
2535 askQuestion "Enter the autodl-irssi password (this is not your login password):" ""
2536 autodlPassword="$answer"
2537 isValidPassword "$autodlPassword" && break
2538 echo "${CWARNING}Invalid password. Try again.$CEND"
2539 done
2540 fi
2541
2542 if [ "$RUTORRENT_PASSWORD_PROTECTED" = y ]; then
2543 while true; do
2544 askQuestion "Enter your ruTorrent password:" ""
2545 webpass="$answer"
2546 isValidPassword "$webpass" && break
2547 echo "${CWARNING}Invalid password. Try again.$CEND"
2548 done
2549 fi
2550
2551 USERS="$USERS $osUser:$autodlPassword:$webUser:$webpass"
2552 else
2553 USERS="$USERS $osUser"
2554 fi
2555}
2556
2557installUser() {
2558 local userPluginDir="$1"
2559 local osUser="$2"
2560 local webUser="${3:-$osUser}"
2561 local port="$4"
2562 local autodlPassword="$5"
2563
2564 getUserGroup "$osUser"
2565 getUserDir "$osUser"
2566
2567 cat << EOF
2568
2569========================= ${CGREEN}Installing autodl-irssi$CEND =========================
2570Use the ruTorrent plugin: $CGREEN$USE_RUTORRENT_PLUGIN$CEND
2571OS user: $CGREEN$osUser$CEND
2572EOF
2573 if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2574 [ "$RUTORRENT_PASSWORD_PROTECTED" = y ] && echo "ruTorrent user: $CGREEN$webUser$CEND"
2575 echo "port: $CGREEN$port$CEND"
2576 echo "password: $CGREEN$autodlPassword$CEND"
2577 fi
2578 cat << EOF
2579group: $CGREEN$group$CEND
2580home: $CGREEN$userDir$CEND
2581
2582EOF
2583 if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2584 isValidPortNumber "$port" || errorExit "Invalid port number: $port"
2585 isValidPassword "$autodlPassword" || errorExit "Invalid password: $autodlPassword"
2586 isValidWebUser "$webUser" || errorExit "Invalid web user: $webUser"
2587 fi
2588
2589 mkdir -p "$userDir/.irssi/scripts/autorun"
2590 cd "$userDir/.irssi/scripts" || errorExit "Could not CD into user dir. Run the script as root."
2591 echo "${CMSG}Downloading autodl-irssi.zip...$CEND"
2592 if ! downloadFile autodl-irssi.zip "$AUTODL_IRSSI_ZIP_URL"; then
2593 errorExit "Could not download autodl-irssi zip file"
2594 fi
2595 echo "${CMSG}Unpacking autodl-irssi...$CEND"
2596 unzip -o autodl-irssi.zip > /dev/null || errorExit "Could not unpack autodl-irssi zip file"
2597 rm -f autodl-irssi.zip
2598 cp autodl-irssi-master/autodl-irssi.pl autorun/ || errorExit "Could not copy autodl-irssi.pl to Irssi autorun dir."
2599 mkdir -p "$userDir/.autodl"
2600 touch "$userDir/.autodl/autodl.cfg"
2601 if ! [ -s "$userDir/.autodl/autodl.cfg" ]; then
2602 [ "$INSTALL_RUTORRENT" = y ] && cat > "$userDir/.autodl/autodl.cfg" << EOF
2603[options]
2604upload-type = rtorrent
2605EOF
2606 fi
2607
2608 if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2609 if [ ! -d "$AUTODL_IRSSI_PLUGIN_DIR" ]; then
2610 errorExit "The autodl-irssi ruTorrent plugin has not been installed. Install it."
2611 fi
2612
2613 cat > "$userDir/.autodl/autodl2.cfg" << EOF
2614[options]
2615gui-server-port = $port
2616gui-server-password = $autodlPassword
2617EOF
2618
2619 rm -f "$AUTODL_IRSSI_PLUGIN_DIR/conf.php"
2620 mkdir -p "$userPluginDir"
2621 cat > "$userPluginDir/conf.php" << EOF
2622<?php
2623\$autodlPort = $port;
2624\$autodlPassword = "$autodlPassword";
2625?>
2626EOF
2627 [ $? -eq 0 ] || errorExit "Could not write to $userPluginDir/conf.php. Run this script as root."
2628 # Only set perms to 0400 if the code knows the owner (web server owner) and will reset it
2629 [ "$ISROOT" = y ] && [ "$INSTALL_RUTORRENT" = y ] && chmod 0400 "$userPluginDir/conf.php"
2630 else
2631 # Don't use the autodl-irssi ruTorrent plugin
2632 : > "$userDir/.autodl/autodl2.cfg"
2633 fi
2634
2635 # The Perl module isn't loaded by default
2636 if [ "$IRSSI_LOAD_PERL" = y ]; then
2637 if [ ! -f "$userDir/.irssi/startup" ] || ! grep -q 'load perl' "$userDir/.irssi/startup"; then
2638 echo "load perl" >> "$userDir/.irssi/startup"
2639 fi
2640 fi
2641
2642 # Make sure we redownload the tracker files since the ones in the zip file are possibly
2643 # old versions.
2644 local autodlStateFile="$userDir/.autodl/AutodlState.xml"
2645 [ -f "$autodlStateFile" ] && sed_i 'g/<trackers-version>/d' "$autodlStateFile"
2646
2647 resetOwner "$osUser" "$userDir/.autodl" "$userDir/.irssi"
2648 chmod 0700 "$userDir/.autodl" "$userDir/.irssi"
2649}
2650
2651getRutorrentUserConfDir() {
2652 userConfDir="$RUTORRENT_BASE_PATH/conf/users/$webUser"
2653}
2654
2655getRutorrentUserShareDir() {
2656 userShareDir="$RUTORRENT_BASE_PATH/share/users/$webUser"
2657}
2658
2659resetRutorrentUserPermissions() {
2660 for packedUser in $USERS; do
2661 extractPackedUser $packedUser
2662 getRutorrentUserConfDir
2663 getRutorrentUserShareDir
2664 # Make sure only the web server and the user itself can access its share/conf dirs
2665 chown $osUser:$WWW_GROUP "$userShareDir" "$userConfDir"
2666 chmod 0770 "$userShareDir" "$userConfDir"
2667 done
2668}
2669
2670############################################################################
2671#
2672# This is where we start
2673#
2674############################################################################
2675
2676SELINUX_ENABLED=n
2677isProgramInstalled selinuxenabled && selinuxenabled && SELINUX_ENABLED=y
2678echo "SELinux enabled: $SELINUX_ENABLED"
2679
2680ISROOT=n
2681[ $(id -u) -eq 0 ] && ISROOT=y
2682echo "Is root user: $ISROOT"
2683
2684if [ $# -gt 0 ]; then
2685 parseCommandLine "$@"
2686 INTERACTIVE=n
2687else
2688 INTERACTIVE=y
2689fi
2690
2691detectOs
2692cat << EOF
2693Detected OS: $CGREEN$os_long$CEND
2694Type: $CGREEN$os$CEND
2695
2696Type sh $0 --help for all command line options.
2697EOF
2698
2699osHandler_$os init
2700
2701if [ "$INTERACTIVE" = y ]; then
2702 if [ "$ISROOT" = n ]; then
2703 cat << EOF
2704$CRED
2705You're not the root user! This install script may fail if you're not the root
2706user. To start it as the root user do one of the following:
2707
2708Ubuntu and Ubuntu clones:
2709 ${CGREEN}sudo sh $0$CRED
2710
2711Any other OS:
2712 ${CGREEN}su
2713 sh $0$CRED
2714$CEND
2715EOF
2716 waitenter "Press Ctrl+C to exit or ENTER to continue..."
2717 fi
2718
2719 cat << EOF
2720$CMSG
2721Press ENTER to use the default answer in [brackets].$CEND
2722EOF
2723
2724 webServers=
2725 canInstallLighttpd && webServers="$webServers lighttpd"
2726 canInstallNginx && webServers="$webServers nginx"
2727 canInstallApache && webServers="$webServers apache"
2728 if [ -n "$webServers" ]; then
2729 cat << EOF
2730$CQUESTION
2731If you want to install ruTorrent you must install a web server, eg. Apache.
2732If you've already installed another web server, you must first uninstall it or
2733disable it. List of supported web servers:$CEND
2734EOF
2735 canInstallLighttpd && echo " ${CGREEN}lighttpd$CEND ${CQUESTION}lighttpd web server (lightweight)$CEND"
2736 canInstallNginx && echo " ${CGREEN}nginx$CEND ${CQUESTION}nginx web server (lightweight)$CEND"
2737 canInstallApache && echo " ${CGREEN}apache$CEND ${CQUESTION}Apache web server$CEND"
2738 echo " ${CGREEN}none$CEND ${CQUESTION}Don't install a web server$CEND"
2739 while true; do
2740 INSTALL_WEB_SERVER=
2741 echo "${CQUESTION}Select one of:$CGREEN$webServers none$CEND"
2742 askQuestion "Enter name of web server" "$(getFirst $webServers)"
2743 [ "$answer" = none ] && break
2744 INSTALL_WEB_SERVER="$answer"
2745 arrayIsPresent $INSTALL_WEB_SERVER $webServers && break
2746 done
2747 if [ -n "$INSTALL_WEB_SERVER" ]; then
2748 askYesNo "Do you want to install ruTorrent?" "Yes"
2749 INSTALL_RUTORRENT="$answer"
2750 else
2751 INSTALL_RUTORRENT=n
2752 fi
2753 fi
2754
2755 if canInstallRtorrent; then
2756 cat << EOF
2757$CQUESTION
2758ruTorrent requires a working rtorrent built with XML-RPC support.$CEND
2759EOF
2760 askYesNo "Do you want to build rtorrent?" "Yes"
2761 BUILD_RTORRENT="$answer"
2762 fi
2763
2764 askYesNo "Do you want to install the autodl-irssi ruTorrent plugin?" "Yes"
2765 USE_RUTORRENT_PLUGIN="$answer"
2766
2767 if [ "$INSTALL_RUTORRENT" = y ]; then
2768 REINSTALL_RUTORRENT_PLUGIN=n
2769 RUTORRENT_PASSWORD_PROTECTED=y
2770 elif [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2771 echo ""
2772 while true; do
2773 echo "${CQUESTION}The ruTorrent www base path is where you installed ruTorrent.$CEND"
2774 askQuestion "What is the ruTorrent www base path, eg. /var/www/rutorrent:" ""
2775 RUTORRENT_BASE_PATH="$answer"
2776 isValidRutorrentBasePath "$RUTORRENT_BASE_PATH" && break
2777
2778 echo "$CWARNING$RUTORRENT_BASE_PATH is not the ruTorrent base path.$CEND"
2779 done
2780
2781 initPluginDirVar
2782 if [ -d "$AUTODL_IRSSI_PLUGIN_DIR" ]; then
2783 echo ""
2784 askYesNo "The autodl-irssi ruTorrent plugin seems to be installed. Do you want to re-install it?" "No"
2785 REINSTALL_RUTORRENT_PLUGIN="$answer"
2786 else
2787 REINSTALL_RUTORRENT_PLUGIN=n
2788 fi
2789
2790 cat << EOF
2791$CQUESTION
2792To use more than one ruTorrent user, you must password protect ruTorrent.$CEND
2793EOF
2794 askYesNo "Is ruTorrent password protected?" "No"
2795 RUTORRENT_PASSWORD_PROTECTED="$answer"
2796 else
2797 RUTORRENT_PASSWORD_PROTECTED=n
2798 fi
2799
2800 if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2801 INSTALL_AUTODL_IRSSI=y
2802 else
2803 askYesNo "Do you want to install autodl-irssi?" "Yes"
2804 INSTALL_AUTODL_IRSSI="$answer"
2805 fi
2806
2807 if canInstallService && ([ "$INSTALL_AUTODL_IRSSI" = y ] || [ "$INSTALL_RUTORRENT" = y ]); then
2808 cat << EOF
2809$CQUESTION
2810If you want to automatically start Irssi and rtorrent when the computer boots,
2811install the startup script.$CEND
2812EOF
2813 askYesNo "Do you want to install the startup script?" "Yes"
2814 INSTALL_STARTUP_SCRIPT="$answer"
2815 fi
2816
2817 askUser=n
2818 if [ "$USE_RUTORRENT_PLUGIN" = y ] || [ "$INSTALL_AUTODL_IRSSI" = y ] || \
2819 [ "$INSTALL_STARTUP_SCRIPT" = y ] || [ "$INSTALL_RUTORRENT" = y ]; then
2820 askUser=y
2821 fi
2822 if [ "$askUser" = y ]; then
2823 if [ "$RUTORRENT_PASSWORD_PROTECTED" = n ]; then
2824 cat << EOF
2825$CQUESTION
2826This is the user running rtorrent and/or Irssi.$CEND
2827${CWARNING}Don't use the root user. Use a normal user!$CEND
2828EOF
2829 askOsUser
2830 addUser "$answer" ""
2831 else
2832 while true; do
2833 cat << EOF
2834$CQUESTION
2835===================== USER =====================
2836This is the user running rtorrent and/or Irssi.
2837${CWARNING}Don't use the root user. Use a normal user!$CEND
2838${CCYAN}Press ENTER to stop adding users.$CEND
2839EOF
2840 askOsUser y
2841 osUser="$answer"
2842 [ -z "$osUser" ] && break
2843
2844 while true; do
2845 cat << EOF
2846$CQUESTION
2847The ruTorrent user is the name you use to log in to ruTorrent.$CEND
2848EOF
2849 askQuestion "Enter ruTorrent user:" "$osUser"
2850 webUser="$answer"
2851 isValidWebUser "$webUser" && break
2852 echo "${CWARNING}Invalid web user name '$webUser'. Use only lower case letters."
2853 done
2854
2855 addUser "$osUser" "$webUser"
2856 done
2857 fi
2858 fi
2859
2860 if canInstallVsftpd; then
2861 cat << EOF
2862$CQUESTION
2863vsftpd is a very secure FTP daemon.$CEND
2864EOF
2865 askYesNo "Do you want to install vsftpd?" "Yes"
2866 INSTALL_VSFTPD="$answer"
2867
2868 if [ "$INSTALL_VSFTPD" = y ]; then
2869 askYesNo "Do you want to use encrypted FTP (FTPES)" "Yes"
2870 USE_ENCRYPTED_FTP="$answer"
2871
2872 port=$DEFAULT_PORT_FTP
2873 [ "$USE_ENCRYPTED_FTP" = y ] && port=$DEFAULT_PORT_FTPES
2874 askQuestion "Enter FTP port number" "$port"
2875 FTP_PORT="$answer"
2876 fi
2877 fi
2878
2879 if canInstallWebmin; then
2880 cat << EOF
2881$CQUESTION
2882Webmin is a web-based administration tool for your OS.$CEND
2883EOF
2884 askYesNo "Do you want to install Webmin?" "Yes"
2885 INSTALL_WEBMIN="$answer"
2886 fi
2887fi
2888
2889cmdline="sh $0"
2890[ "$USE_RUTORRENT_PLUGIN" = y ] && cmdline="$cmdline -p"
2891[ "$REINSTALL_RUTORRENT_PLUGIN" = y ] && cmdline="$cmdline -i"
2892[ "$INSTALL_AUTODL_IRSSI" = y ] && cmdline="$cmdline -a"
2893for user in $USERS; do cmdline="$cmdline -u $user"; done
2894[ "$RUTORRENT_PASSWORD_PROTECTED" = y ] && cmdline="$cmdline -w"
2895[ -n "$RUTORRENT_BASE_PATH" ] && cmdline="$cmdline -r '$RUTORRENT_BASE_PATH'"
2896[ "$INSTALL_STARTUP_SCRIPT" = y ] && cmdline="$cmdline -s"
2897if [ -z "$INSTALL_WEB_SERVER" ]; then
2898 :
2899elif [ "$INSTALL_WEB_SERVER" = apache ]; then
2900 cmdline="$cmdline --apache"
2901elif [ "$INSTALL_WEB_SERVER" = nginx ]; then
2902 cmdline="$cmdline --nginx"
2903elif [ "$INSTALL_WEB_SERVER" = lighttpd ]; then
2904 cmdline="$cmdline --lighttpd"
2905else
2906 errorExit "Invalid web server: $INSTALL_WEB_SERVER"
2907fi
2908[ "$BUILD_RTORRENT" = y ] && cmdline="$cmdline --rtorrent"
2909[ "$INSTALL_RUTORRENT" = y ] && cmdline="$cmdline --rutorrent"
2910[ "$INSTALL_VSFTPD" = y ] && cmdline="$cmdline --vsftpd"
2911[ -n "$FTP_PORT" ] && cmdline="$cmdline --ftp-port $FTP_PORT"
2912[ "$USE_ENCRYPTED_FTP" = y ] && cmdline="$cmdline --ftpes"
2913[ "$INSTALL_WEBMIN" = y ] && cmdline="$cmdline --webmin"
2914
2915cat << EOF
2916
2917You can execute this command as the root user (Ubuntu: use ${CRED}sudo$CEND):
2918 $CGREEN$cmdline$CEND
2919
2920Use the autodl-irssi ruTorrent plugin: $USE_RUTORRENT_PLUGIN
2921Re-install the autodl-irssi ruTorrent plugin: $REINSTALL_RUTORRENT_PLUGIN
2922Install autodl-irssi: $INSTALL_AUTODL_IRSSI
2923Users: $USERS
2924ruTorrent is password protected: $RUTORRENT_PASSWORD_PROTECTED
2925ruTorrent base path: $RUTORRENT_BASE_PATH
2926Install startup script: $INSTALL_STARTUP_SCRIPT
2927Install web server: $INSTALL_WEB_SERVER
2928Build rtorrent: $BUILD_RTORRENT
2929Install ruTorrent: $INSTALL_RUTORRENT
2930Install vsftpd: $INSTALL_VSFTPD
2931FTP port: $FTP_PORT
2932Use FTPES: $USE_ENCRYPTED_FTP
2933Install Webmin: $INSTALL_WEBMIN
2934EOF
2935
2936if [ -n "$INSTALL_WEB_SERVER" ]; then
2937 for port in $HTTP_PORT $HTTPS_PORT; do
2938 isPortUsed $port || continue
2939 cat << EOF
2940$CWARNING
2941Port $port is in use. If it's not used by $INSTALL_WEB_SERVER, you may need to disable or
2942uninstall that other web server before continuing.$CEND
2943EOF
2944 done
2945fi
2946
2947if [ "$INTERACTIVE" = y ]; then
2948 echo ""
2949 waitenter "Press Ctrl+C to cancel or ENTER to install."
2950fi
2951
2952osHandler_$os init2
2953initUsers
2954initPluginDirVar
2955
2956[ -n "$INSTALL_WEB_SERVER" ] || [ "$INSTALL_RUTORRENT" = y ] && RUTORRENT_PASSWORD_PROTECTED=y
2957[ "$INSTALL_RUTORRENT" = y ] && [ -z "$INSTALL_WEB_SERVER" ] && errorExit "You must install a web server if you want to install ruTorrent, eg. use --apache --rutorrent"
2958[ "$INSTALL_RUTORRENT" = y ] && REINSTALL_RUTORRENT_PLUGIN=n
2959
2960[ "$BUILD_RTORRENT" = y ] && ! canInstallRtorrent && errorExit "Can't build rtorrent."
2961[ "$INSTALL_STARTUP_SCRIPT" = y ] && ! canInstallService && errorExit "Can't install startup script."
2962[ "$INSTALL_VSFTPD" = y ] && ! canInstallVsftpd && errorExit "Can't install vsftpd."
2963[ "$INSTALL_WEBMIN" = y ] && ! canInstallWebmin && errorExit "Can't install webmin."
2964
2965if [ -z "$INSTALL_WEB_SERVER" ]; then
2966 :
2967elif [ "$INSTALL_WEB_SERVER" = apache ]; then
2968 canInstallApache || errorExit "Can't install Apache."
2969elif [ "$INSTALL_WEB_SERVER" = nginx ]; then
2970 canInstallNginx || errorExit "Can't install nginx."
2971elif [ "$INSTALL_WEB_SERVER" = lighttpd ]; then
2972 canInstallLighttpd || errorExit "Can't install lighttpd."
2973else
2974 errorExit "Invalid web server: $INSTALL_WEB_SERVER"
2975fi
2976
2977[ -n "$FTP_PORT" ] && [ "$FTP_PORT" -lt 1 -o "$FTP_PORT" -gt 65535 ] && errorExit "Invalid FTP port: $FTP_PORT"
2978
2979if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
2980 if [ -z "$INSTALL_WEB_SERVER" ] && ! isValidRutorrentBasePath "$RUTORRENT_BASE_PATH"; then
2981 errorExit "$RUTORRENT_BASE_PATH is not a valid ruTorrent base path."
2982 fi
2983fi
2984
2985if [ "$INSTALL_AUTODL_IRSSI" = y ]; then
2986 cat << EOF
2987${CMSG}Installing required tools and Perl modules...
2988Some Perl modules may not be present, but will be installed from CPAN.$CEND
2989EOF
2990else
2991 echo "${CMSG}Installing required tools...$CEND"
2992fi
2993osHandler_$os installTools
2994setSvnOpts
2995[ "$INSTALL_AUTODL_IRSSI" = y ] && osHandler_$os installAutodlTools
2996
2997verifyInstalledPrograms
2998
2999[ "$INSTALL_AUTODL_IRSSI" = y ] && installMissingPerlModules
3000
3001cat << EOF
3002$CMSG
3003All required programs and Perl modules are now installed. Ignore any errors you
3004saw.$CEND
3005EOF
3006
3007INSTALLED_RTORRENT=n
3008if [ "$BUILD_RTORRENT" = y ]; then
3009 cat << EOF
3010$CMSG
3011Building rtorrent and dependencies...$CEND
3012EOF
3013 installRtorrent
3014 INSTALLED_RTORRENT=y
3015fi
3016
3017if [ -z "$INSTALL_WEB_SERVER" ]; then
3018 :
3019elif [ "$INSTALL_WEB_SERVER" = apache ]; then
3020 echo ""
3021 echo "${CMSG}Installing Apache$CEND"
3022 osHandler_$os installApache
3023 installUnrar
3024elif [ "$INSTALL_WEB_SERVER" = nginx ]; then
3025 echo ""
3026 echo "${CMSG}Installing nginx$CEND"
3027 installNginx
3028elif [ "$INSTALL_WEB_SERVER" = lighttpd ]; then
3029 echo ""
3030 echo "${CMSG}Installing lighttpd$CEND"
3031 installLighttpd
3032else
3033 errorExit "Invalid web server: $INSTALL_WEB_SERVER"
3034fi
3035
3036if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
3037 if isProgramInstalled php; then
3038 installMissingPhpModules
3039 else
3040 cat << EOF
3041$CWARNING
3042Could not find the php executable. PHP is not installed or the PHP CLI version
3043is not installed. The autodl-irssi ruTorrent plugin requires the following PHP
3044modules:
3045 $CGREEN$REQUIRED_PHP_MODULES$CWARNING
3046They're normally installed and enabled by default. If not you will need to
3047install them (if needed) and then enable each one in php.ini, eg.
3048extension=MODULE.so and then restart your web server.$CEND
3049EOF
3050 fi
3051fi
3052
3053if [ "$INSTALL_RUTORRENT" = y ]; then
3054 isProgramInstalled php || errorExit "php is not installed!"
3055 verifyWebServerVars
3056 echo ""
3057 echo "${CMSG}Installing ruTorrent$CEND"
3058 [ -d "$WWW_ROOT" ] || errorExit "Invalid web root: '$WWW_ROOT' (does not exist)"
3059 RUTORRENT_DIRNAME=rutorrent
3060
3061 [ -f "$WWW_ROOT/index.html" ] || cat > "$WWW_ROOT/index.html" << EOF
3062<html><head><title>Root page</title></head><body>
3063<a href="$RUTORRENT_DIRNAME/">ruTorrent</a>
3064</body></html>
3065EOF
3066
3067 cd "$WWW_ROOT"
3068 rm -rf "$RUTORRENT_DIRNAME"
3069 tmpName=rutorrent-tmp
3070 rm -rf $tmpName
3071 if ! git clone "$RUTORRENT_TRUNK_DIR" $tmpName/rutorrent >/dev/null; then
3072 # Subversion failed. Try the official tar balls
3073 mkdir -p $tmpName
3074 cd $tmpName
3075 downloadFile "$RUTORRENT_CORE_NAME" "$RUTORRENT_CORE_URL" "$RUTORRENT_CORE_URL2" || errorExit "Could not download ruTorrent."
3076 downloadFile "$RUTORRENT_PLUGINS_NAME" "$RUTORRENT_PLUGINS_URL" "$RUTORRENT_PLUGINS_URL2" || errorExit "Could not download ruTorrent plugins."
3077 for name in "$RUTORRENT_CORE_NAME" "$RUTORRENT_PLUGINS_NAME"; do
3078 tar xzf "$name" || errorExit "Could not unpack $name"
3079 rm -f "$name"
3080 done
3081 cd ..
3082 fi
3083 cd $tmpName
3084 RUTORRENT_BASE_PATH="$WWW_ROOT/$RUTORRENT_DIRNAME"
3085 initPluginDirVar
3086 mv rutorrent/plugins/ .
3087 mv rutorrent/ "$RUTORRENT_BASE_PATH"
3088 mkdir -p "$RUTORRENT_BASE_PATH/plugins"
3089 for plugin in $RUTORRENT_PLUGINS; do
3090 if [ -d "plugins/$plugin/" ]; then
3091 echo "${CMSG}Installing ruTorrent plugin: $plugin$CEND..."
3092 mv plugins/$plugin/ "$RUTORRENT_BASE_PATH/plugins/" || errorExit "Could not install plugin '$plugin'."
3093 else
3094 echo "${CWARNING}Can't install missing plugin $plugin!$CEND"
3095 fi
3096 done
3097 cd ..
3098 rm -rf $tmpName
3099 cp "$RUTORRENT_BASE_PATH/favicon.ico" "$WWW_ROOT"
3100
3101 i=1
3102 touch "$WWW_PASSWORD_FILE"
3103 resetAuthPasswordFilePermissions
3104 detectHtpasswd
3105 for packedUser in $USERS; do
3106 extractPackedUser $packedUser
3107 getRutorrentUserConfDir
3108 getRutorrentUserShareDir
3109 getUserScgiSocketPath "$osUser"
3110 getRtorrentDirs "$osUser"
3111
3112 # Create user's ruTorrent config.php
3113 rpcMount="$(getUserRpcMount $i)"
3114 mkdir -p "$userConfDir"
3115
3116 rutConfigFile="$userConfDir/config.php"
3117 if [ "$SCGI_USE_UNIX_DOMAIN_SOCKET" = y ]; then
3118 cat > "$rutConfigFile" << EOF
3119<?php
3120\$scgi_port = 0;
3121\$scgi_host = "unix://$scgiSocketPath";
3122\$XMLRPCMountPoint = "$rpcMount";
3123?>
3124EOF
3125 exitCode=$?
3126 else
3127 cat > "$rutConfigFile" << EOF
3128<?php
3129\$scgi_port = $scgiPort;
3130\$scgi_host = "$SCGI_HOST";
3131\$XMLRPCMountPoint = "$rpcMount";
3132?>
3133EOF
3134 exitCode=$?
3135 fi
3136 [ $exitCode -eq 0 ] || errorExit "Could not write to file $rutConfigFile"
3137
3138 # Create user's directory to prevent certain errors the first time ruTorrent is started
3139 mkdir -p "$userShareDir/settings"
3140 mkdir -p "$userShareDir/torrents"
3141 chmod 0777 "$userShareDir/settings" "$userShareDir/torrents"
3142
3143 # Setup rtorrent
3144 mkdir -p "$RTORRENT_DOWNLOAD_DIR"
3145 mkdir -p "$RTORRENT_WATCH_DIR"
3146 mkdir -p "$RTORRENT_SESSION_DIR"
3147 rtorrentRc="$userDir/.rtorrent.rc"
3148 [ -f "$rtorrentRc" ] && mv -f "$rtorrentRc" "$rtorrentRc-backup"
3149 cat > "$rtorrentRc" << EOF
3150$(if [ "$SCGI_USE_UNIX_DOMAIN_SOCKET" = y ]; then
3151 cat << EOF2
3152execute = {sh,-c,rm -f $scgiSocketPath}
3153scgi_local = $scgiSocketPath
3154execute = {sh,-c,chmod 0666 $scgiSocketPath}
3155EOF2
3156else
3157 echo "scgi_port = $SCGI_HOST:$scgiPort"
3158fi)
3159encoding_list = UTF-8
3160system.umask.set = $DEFAULT_UMASK
3161port_range = $rtorrentPort-$rtorrentPort
3162port_random = no
3163check_hash = no
3164directory = $RTORRENT_DOWNLOAD_DIR
3165session = $RTORRENT_SESSION_DIR
3166encryption = allow_incoming, try_outgoing, enable_retry
3167schedule = watch_directory,1,1,"load_start=$RTORRENT_WATCH_DIR/*.torrent"
3168#schedule = untied_directory,5,5,"stop_untied=$RTORRENT_WATCH_DIR/*.torrent"
3169trackers.enable = 1
3170#min_peers = 40
3171#max_peers = 100
3172#min_peers_seed = 10
3173#max_peers_seed = 50
3174#max_uploads = 15
3175#download_rate = 0
3176#upload_rate = 0
3177use_udp_trackers = yes
3178dht = auto
3179dht_port = 6881
3180peer_exchange = yes
3181#hash_read_ahead = 10
3182#hash_interval = 100
3183#hash_max_tries = 10
3184EOF
3185 PHP_BIN_PATH=$(which php 2> /dev/null)
3186 COMMENT=
3187 [ -x "$PHP_BIN_PATH" ] || COMMENT="#" PHP_BIN_PATH=/path/to/php
3188 cat >> "$rtorrentRc" << EOF
3189${COMMENT}execute = {sh,-c,$PHP_BIN_PATH $RUTORRENT_BASE_PATH/php/initplugins.php $webUser &}
3190EOF
3191
3192 # Add user to web server's password file
3193 sed_i "g/^$webUser:/d" "$WWW_PASSWORD_FILE"
3194 $htpasswd -b "$WWW_PASSWORD_FILE" "$webUser" "$webPass" || errorExit "Could not add user to password file"
3195 resetAuthPasswordFilePermissions
3196
3197 resetOwner "$osUser" "$rtorrentRc" "$userDir" "$RTORRENT_DOWNLOAD_DIR" "$RTORRENT_WATCH_DIR" "$RTORRENT_SESSION_DIR"
3198
3199 # Required so some ruTorrent plugins work, eg. _getdir
3200 chmod 0755 "$userDir"
3201
3202 # Protect some dirs and files, giving only the user and the web server
3203 # access. We need to do this since we set perms to 0755 above, or if
3204 # the perms already were 0755 to begin with.
3205 if [ -n "$WWW_GROUP" ]; then
3206 chmod 0600 "$rtorrentRc"
3207 for dir in $RTORRENT_REL_DOWNLOAD_DIR $RTORRENT_REL_WATCH_DIR $RTORRENT_REL_SESSION_DIR; do
3208 chown $osUser:$WWW_GROUP "$userDir/$dir"
3209 chmod 0770 "$userDir/$dir"
3210 done
3211 fi
3212
3213 i=$(expr $i + 1)
3214 done
3215
3216 [ "$CREATE_ONE_PASSWORD_FILE_PER_USER" = y ] && createOnePasswordFilePerUser
3217fi
3218
3219if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
3220 [ -z "$RUTORRENT_BASE_PATH" ] && errorExit "Invalid ruTorrent base path."
3221
3222 [ "$REINSTALL_RUTORRENT_PLUGIN" = y ] && rm -rf "$AUTODL_IRSSI_PLUGIN_DIR"
3223 mkdir -p "$RUTORRENT_BASE_PATH/plugins"
3224 cd "$RUTORRENT_BASE_PATH/plugins"
3225
3226 if [ -d "$AUTODL_IRSSI_PLUGIN_DIR" ]; then
3227 echo "${CMSG}The autodl-irssi ruTorrent plugin dir already exists. Updating it...$CEND"
3228 cd "$AUTODL_IRSSI_PLUGIN_DIR"
3229 if ! svn up $SVN_OPTS > /dev/null; then
3230 errorExit "Could not update the autodl-irssi ruTorrent plugin. Run the script as root."
3231 fi
3232 else
3233 echo "${CMSG}Downloading the autodl-irssi ruTorrent plugin...$CEND"
3234 if ! git clone "$GIT_PATH_RUTORRENT_PLUGIN" autodl-irssi > /dev/null; then
3235 errorExit "Could not check out the autodl-irssi ruTorrent plugin"
3236 fi
3237 fi
3238fi
3239
3240if [ "$INSTALL_AUTODL_IRSSI" = y ]; then
3241 if [ "$RUTORRENT_PASSWORD_PROTECTED" = y ]; then
3242 for packedUser in $USERS; do
3243 extractPackedUser $packedUser
3244 installUser "$RUTORRENT_BASE_PATH/conf/users/$webUser/plugins/autodl-irssi" "$osUser" "$webUser" "$autodlPort" "$autodlPassword"
3245 done
3246 else
3247 for packedUser in $USERS; do
3248 extractPackedUser $packedUser
3249 installUser "$AUTODL_IRSSI_PLUGIN_DIR" "$osUser" "$webUser" "$autodlPort" "$autodlPassword"
3250 [ "$USE_RUTORRENT_PLUGIN" = y ] && break
3251 done
3252 fi
3253fi
3254
3255if [ "$INSTALL_RUTORRENT" = y ]; then
3256 verifyWebServerVars
3257 resetWebServerPermissions
3258 resetRutorrentUserPermissions
3259 # Restart it just in case we enabled/installed PHP modules.
3260 osHandler_$os restart_$INSTALL_WEB_SERVER
3261fi
3262
3263if [ "$INSTALL_VSFTPD" = y ]; then
3264 echo "${CMSG}Installing vsftpd...$CEND"
3265 osHandler_$os installVsftpd
3266fi
3267
3268if [ "$INSTALL_WEBMIN" = y ]; then
3269 cd
3270 rm -rf webmin-*/ webmin*.tar.gz
3271 if ! downloadFile webmin.tar.gz "$WEBMIN_URL"; then
3272 errorExit "Could not download Webmin."
3273 fi
3274 tar xzf webmin.tar.gz
3275 rm -f webmin.tar.gz
3276 cd webmin-*/ || errorExit "Could not CD to webmin dir"
3277 osHandler_$os preWebminInstall
3278 [ -x "setup.sh" ] || errorExit "Missing Webmin setup.sh file or not executable."
3279 cat << EOF
3280$CMSG
3281Starting Webmin installer. Use another port than 10000, enable SSL, start webmin
3282at boot, and use a strong admin password.$CEND
3283$CWARNING
3284When it asks you if it should use SSL and whether it should start at boot,
3285type y.$CEND
3286EOF
3287 ./setup.sh /usr/local/webmin
3288 osHandler_$os postWebminInstall
3289 cd
3290 rm -rf webmin-*/
3291fi
3292
3293if [ "$INSTALL_RUTORRENT" = y ]; then
3294 # Some plugins will fail unless they can write to the /tmp directory
3295 # We MUST do this AFTER installing Webmin since it will reset the perms!
3296 chmod 1777 /tmp
3297fi
3298
3299if [ "$INSTALL_STARTUP_SCRIPT" = y ]; then
3300 for packedUser in $USERS; do
3301 extractPackedUser $packedUser
3302 echo "${CMSG}Installing service for user $osUser.$CEND"
3303 osHandler_$os installAutodlService $osUser
3304 done
3305fi
3306
3307echo ""
3308echo "${CGREEN}================================= DONE =================================$CEND"
3309[ "$INSTALLED_RTORRENT" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Built and installed rtorrent with XML-RPC support$CEND"
3310[ -n "$INSTALL_WEB_SERVER" ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed and configured web server ($INSTALL_WEB_SERVER)$CEND"
3311[ "$INSTALL_VSFTPD" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed and configured FTP server (vsftpd)$CEND"
3312[ "$INSTALL_RUTORRENT" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed ruTorrent$CEND"
3313[ "$USE_RUTORRENT_PLUGIN" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed/updated the autodl-irssi ruTorrent plugin$CEND"
3314[ "$INSTALL_AUTODL_IRSSI" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed autodl-irssi$CEND"
3315[ "$INSTALL_STARTUP_SCRIPT" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed and started Irssi and rtorrent service$CEND"
3316[ "$INSTALL_WEBMIN" = y ] && echo "${CDGREEN}[+]$CEND ${CGREEN}Installed Webmin$CEND"
3317
3318if [ "$INSTALL_RUTORRENT" = y ]; then
3319 getIpAddress
3320 cat << EOF
3321
3322${CMSG}ruTorrent URLs.$CEND ${CWARNING}Verify that the IP address below is correct!$CEND
3323 ${CMAGENTA}http://$OUR_IP_ADDRESS/$RUTORRENT_DIRNAME/$CEND
3324 ${CMAGENTA}https://$OUR_IP_ADDRESS/$RUTORRENT_DIRNAME/$CEND
3325EOF
3326fi
3327
3328if [ "$INSTALL_RUTORRENT" = y ]; then
3329 cat << EOF
3330
3331${CMSG}rtorrent directories$CEND:
3332EOF
3333 for packedUser in $USERS; do
3334 extractPackedUser $packedUser
3335 getRtorrentDirs "$osUser"
3336 cat << EOF
3337${CMSG}User $CGREEN$osUser$CEND:
3338 ${CGREEN}Downloads$CEND : $CMAGENTA$RTORRENT_DOWNLOAD_DIR$CEND
3339 ${CGREEN}Watch dir$CEND : $CMAGENTA$RTORRENT_WATCH_DIR$CEND
3340 ${CGREEN}Session dir$CEND : $CMAGENTA$RTORRENT_SESSION_DIR$CEND
3341 ${CGREEN}rtorrent port$CEND: $CMAGENTA$rtorrentPort$CEND
3342EOF
3343 done
3344fi
3345
3346if [ -n "$INSTALL_WEB_SERVER" ]; then
3347 cat << EOF
3348
3349${CMSG}Web server info$CEND:
3350 ${CGREEN}Web server root$CEND: ${CMAGENTA}$WWW_ROOT$CEND
3351 ${CGREEN}ruTorrent dir$CEND : ${CMAGENTA}$RUTORRENT_BASE_PATH$CEND
3352EOF
3353fi
3354
3355if [ "$INSTALL_VSFTPD" = y ]; then
3356 getIpAddress
3357 cat << EOF
3358$CMSG
3359To log in to the FTP server, use your $(uname -s) login name and password. I
3360guessed the IP address below. Make sure it's correct.$CEND
3361 ${CGREEN}FTP IP address$CEND: ${CMAGENTA}$OUR_IP_ADDRESS$CEND
3362 ${CGREEN}FTP port$CEND: ${CMAGENTA}$FTP_PORT$CEND
3363 ${CGREEN}FTP server type$CEND: $CMAGENTA$FTP_SERVER_TYPE$CEND
3364EOF
3365fi
3366
3367if [ "$INSTALL_WEBMIN" = y ]; then
3368 getIpAddress
3369
3370 WEBMIN_PORT=
3371 WEBMIN_SSL=
3372 WEBMIN_NAME=
3373 WEBMIN_CONFIG=/etc/webmin/miniserv.conf
3374 WEBMIN_USERS=/etc/webmin/miniserv.users
3375 if [ -f $WEBMIN_CONFIG ]; then
3376 WEBMIN_PORT=$(grep '^port=' $WEBMIN_CONFIG | tail -n1 | sed -e 's/^port=\([0-9]*\).*/\1/')
3377 WEBMIN_SSL=$(grep '^ssl=' $WEBMIN_CONFIG | tail -n1 | sed -e 's/^ssl=\([0-9]*\).*/\1/')
3378 WEBMIN_NAME=$(head -n1 $WEBMIN_USERS | cut -d: -f1)
3379 fi
3380 WEBMIN_PORT=${WEBMIN_PORT:-UNKNOWN}
3381 WEBMIN_NAME=${WEBMIN_NAME:-UNKNOWN}
3382
3383 cat << EOF
3384$CMSG
3385Webmin was installed. Port is $WEBMIN_PORT and the user is $WEBMIN_NAME.
3386${CRED}Verify the IP address below.$CEND
3387EOF
3388 if [ -z "$WEBMIN_SSL" ]; then
3389 echo " ${CMAGENTA}http://$OUR_IP_ADDRESS:$WEBMIN_PORT/$CEND"
3390 echo "${CMSG}or:$CEND"
3391 echo " ${CMAGENTA}https://$OUR_IP_ADDRESS:$WEBMIN_PORT/$CEND"
3392 elif [ "$WEBMIN_SSL" = 0 ]; then
3393 echo " ${CMAGENTA}http://$OUR_IP_ADDRESS:$WEBMIN_PORT/$CEND"
3394 else
3395 echo " ${CMAGENTA}https://$OUR_IP_ADDRESS:$WEBMIN_PORT/$CEND"
3396 fi
3397fi
3398
3399if [ -n "$INSTALL_WEB_SERVER" ] || [ "$INSTALL_VSFTPD" = y ] || \
3400 [ "$INSTALL_RUTORRENT" = y ] || [ "$USE_RUTORRENT_PLUGIN" = y ]; then
3401 if [ "$SELINUX_ENABLED" = y ]; then
3402 cat << EOF
3403$CWARNING
3404SELinux is enabled. It could cause some problems with the web server, vsftpd or
3405ruTorrent.
3406EOF
3407 fi
3408fi
3409
3410if [ "$CREATED_CERT_FILE" = y ]; then
3411 cat << EOF
3412$CWARNING
3413A self-signed certificate was created. Your browser or FTP client will most
3414likely warn you about a non-trusted certificate.$CEND
3415EOF
3416fi
3417
3418if [ "$USE_RUTORRENT_PLUGIN" = y ]; then
3419 if isProgramInstalled php; then
3420 detectMissingPhpModules
3421 if [ -n "$MISSING_PHP_MODULES" ]; then
3422 cat << EOF
3423$CWARNING
3424The following PHP modules seem to be missing. It's possible that the
3425autodl-irssi ruTorrent plugin won't work. Missing PHP modules:
3426 $MISSING_PHP_MODULES$CEND
3427EOF
3428 fi
3429 else
3430 cat << EOF
3431$CWARNING
3432Could not find the php executable. Make sure the following PHP modules are
3433enabled or the autodl-irssi ruTorrent plugin won't work:
3434 $REQUIRED_PHP_MODULES$CEND
3435EOF
3436 fi
3437fi