Network play support for scripts/setup.
[disorder] / scripts / setup.in
1 #! /bin/bash
2 #
3 # This file is part of DisOrder
4 # Copyright (C) 2008 Richard Kettlewell
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 # USA
20 #
21
22 set -e
23
24 while [ $# -gt 0 ]; do
25 opt="$1"
26 shift
27 case "$opt" in
28 -h | --help )
29 cat <<EOF
30
31 Usage:
32 scripts/setup [OPTIONS]
33
34 Options:
35 --root ROOT Add a root (can be used multiple times)
36 --encoding ENCODING Filename encoding
37 --port PORT TCP port to listen on or 'none'
38 --smtp-server HOSTNAME SMTP server
39 --email ADDRESS Origin email address
40 --register y|n Enable/disable online registration
41 --play local|network Choose local or network play
42 --mcast ADDRESS PORT Set multicast address and port for --play network
43 -h, --help Display this message
44
45 Sets up a basic DisOrder installation. You must have run 'make install'
46 first. Use scripts/teardown to stop the server and deconfigure.
47
48 EOF
49 exit 0
50 ;;
51 --version | -V )
52 echo "DisOrder scripts/setup _version_"
53 exit 0
54 ;;
55 --root )
56 roots="$roots $1"
57 shift
58 ;;
59 --encoding )
60 encoding="$1"
61 shift
62 ;;
63 --port )
64 port="$1"
65 shift
66 ;;
67 --smtp-server )
68 smtp_server="$1"
69 shift
70 ;;
71 --email )
72 mail_sender="$1"
73 shift
74 ;;
75 --register )
76 register="$1"
77 shift
78 ;;
79 --play )
80 play="$1"
81 shift
82 ;;
83 --mcast )
84 play=network
85 mcast_address="$1"
86 shift
87 mcast_port="$1"
88 shift
89 ;;
90 * )
91 echo >&2 "ERROR: unknown option '$opt'"
92 exit 1
93 ;;
94 esac
95 done
96
97 echo
98 echo ------------------------------------------------------------------------
99 echo "DisOrder setup script"
100
101 case $(uname -s) in
102 Darwin )
103 echo "Mac OS X detected"
104 os=Mac
105 user=jukebox
106 group=jukebox
107 ;;
108 FreeBSD )
109 echo "FreeBSD detected"
110 os=FreeBSD
111 user=jukebox
112 group=jukebox
113 ;;
114 Linux )
115 if grep Debian /etc/issue >/dev/null 2>&1; then
116 echo "You appear to be running Debian - please use .debs instead"
117 echo
118 elif grep Ubuntu /etc/issue >/dev/null 2>&1; then
119 echo "You appear to be running Ubuntu - please use .debs instead"
120 echo
121 fi
122 echo "Linux detected"
123 os=Linux
124 user=jukebox
125 group=jukebox
126 ;;
127 * )
128 echo
129 echo "WARNING: unknown operating system '$(uname -s)'"
130 echo "This script won't be able to do all setup on this platform"
131 os=unknown
132 user=daemon
133 group=daemon
134 ;;
135 esac
136
137 echo
138 echo "This script will:"
139 echo " - overwrite any existing configuration"
140 echo " - set the server up to be run at boot time"
141 echo " - start the server"
142 echo " - set up the web interface"
143 echo
144 echo "If this is not what you want, press ^C."
145 echo ------------------------------------------------------------------------
146
147 if [ -z "$roots" ]; then
148 while :; do
149 echo
150 echo "What directory or directories contain your music files:"
151 echo "(enter one or more directories separated by spaces)"
152 read -r roots
153 ok=true
154 for root in $roots; do
155 if [ ! -d $root ]; then
156 echo "'$root' does not exist"
157 ok=false
158 fi
159 done
160 if $ok; then
161 break
162 fi
163 done
164 fi
165
166 if [ -z "$encoding" ]; then
167 echo
168 echo "What filesystem encoding should I assume for track names?"
169 echo "(e.g. UTF-8, ISO-8859-1, ...)"
170 read -r encoding
171 fi
172
173 if [ -z "$port" ]; then
174 while :; do
175 echo
176 echo "What TCP port should DisOrder listen on?"
177 echo "(enter 'none' for none)"
178 read -r port
179 case $port in
180 none )
181 break
182 ;;
183 [^0-9] )
184 echo "'$port' is not a valid port number"
185 continue
186 ;;
187 * )
188 break
189 ;;
190 esac
191 done
192 fi
193
194 if [ -z "$play" ]; then
195 while :; do
196 echo
197 echo "How do you want to play sound? Enter 'local' to use a local sound"
198 echo "device or 'network' to multicast sound across your network."
199 read -r play
200 case $play in
201 'local' | network )
202 break
203 ;;
204 * )
205 echo "Enter 'local' or 'network'"
206 continue
207 ;;
208 esac
209 done
210 fi
211
212 if [ "x$play" = xnetwork ]; then
213 if [ -z "$mcast_address" ]; then
214 echo
215 echo "Enter destination address for network transmission"
216 echo "(e.g. a multicast address)"
217 read -r mcast_address
218 fi
219 if [ -z "$mcast_port" ]; then
220 while :; do
221 echo
222 echo "Enter destination port for network transmission"
223 read -r mcast_port
224 case $mcast_port in
225 none )
226 break
227 ;;
228 [^0-9] )
229 echo "'$mcast_port' is not a valid port number"
230 continue
231 ;;
232 * )
233 break
234 ;;
235 esac
236 done
237 fi
238 fi
239
240 if [ -z "$smtp_server" ]; then
241 echo
242 echo "What host should DisOrder use as an SMTP server?"
243 read -r smtp_server
244 fi
245
246 if [ -z "$mail_sender" ]; then
247 while :; do
248 echo
249 echo "What address should mail from DisOrder come from?"
250 read -r mail_sender
251 case "$mail_sender" in
252 *@* )
253 break
254 ;;
255 * )
256 echo "Email address must contain an '@' sign"
257 ;;
258 esac
259 done
260 fi
261
262 if [ -z "$register" ]; then
263 while :; do
264 echo
265 echo "Do you want to enable online registration? (Enter 'y' or 'n')"
266 read -r register
267 case $reguser in
268 y | n )
269 break
270 ;;
271 esac
272 done
273 fi
274
275 echo
276 echo "Proposed DisOrder setup:"
277 echo " Music directory: $roots"
278 if [ $port = none ]; then
279 echo " Do not listen on a TCP port"
280 else
281 echo " TCP port to listen on: $port"
282 fi
283 echo " SMTP Server: $smtp_server"
284 echo " Sender address: $mail_sender"
285 echo " Online registration: $register"
286 if [ $play = network ]; then
287 echo " Send sound to: $mcast_address port $mcast_port"
288 fi
289
290 echo "Is this OK? (Enter 'y' or 'n')"
291 read -r ok
292 case $ok in
293 y )
294 ;;
295 * )
296 echo
297 echo "OK, didn't change anything."
298 exit 0
299 ;;
300 esac
301
302 mkdir -p pkgconfdir
303
304 rm -f pkgconfdir/config.new
305 for root in $roots; do
306 echo "collection fs $encoding $root" >> pkgconfdir/config.new
307 done
308 for scratch in slap.ogg scratch.ogg; do
309 echo "scratch pkgdatadir/$scratch" >> pkgconfdir/config.new
310 done
311 echo "user $user" >> pkgconfdir/config.new
312 if [ $port != none ]; then
313 echo "listen 0.0.0.0 $port" >> pkgconfdir/config.new
314 fi
315 if [ $play = network ]; then
316 echo "broadcast $mcast_address $mcast_port" >> pkgconfdir/config.new
317 fi
318 echo "smtp_server $smtp_server" >> pkgconfdir/config.new
319 echo "mail_sender $mail_sender" >> pkgconfdir/config.new
320
321 echo
322 echo "Proposed pkgconfdir/config:"
323 sed < pkgconfdir/config.new 's/^/ /'
324 echo
325 echo "Is this OK? (Enter 'y' or 'n')"
326 read -r ok
327 case $ok in
328 y )
329 ;;
330 * )
331 echo
332 echo "OK, not installing it."
333 rm -f pkgconfdir/config.new
334 exit 0
335 ;;
336 esac
337 echo
338 echo "Installing pkgconfdir/config"
339 mv pkgconfdir/config.new pkgconfdir/config
340
341 if [ ! -f pkgconfdir/options.user ]; then
342 echo "Making sure pkgconfdir/options.user exists"
343 touch pkgconfdir/options.user
344 fi
345
346 # pick ID1 ID2 ... IDn
347 # Echoes an ID matching none of ID1..IDn
348 pick() {
349 local n
350 n=250 # better not choose 0!
351 while :; do
352 ok=true
353 for k in "$@"; do
354 if [ $n = $k ]; then
355 ok=false
356 break
357 fi
358 done
359 if $ok; then
360 echo $n
361 return
362 fi
363 n=$((1+$n))
364 done
365 }
366
367 case $os in
368 Mac )
369 # Apple don't seem to believe in creating a user as a discrete operation
370 if dscl . -read /Groups/$group >/dev/null 2>&1; then
371 echo "$group group already exists"
372 else
373 echo "Creating $group group"
374 gids=$(dscl . -list /Groups PrimaryGroupID|awk '{print $2}')
375 gid=$(pick $gids)
376 echo "(picked gid $gid)"
377 dscl . -create /Groups/$group
378 dscl . -create /Groups/$group PrimaryGroupID $gid
379 dscl . -create /Groups/$group Password \*
380 fi
381 if dscl . -read /Users/$user >/dev/null 2>&1; then
382 echo "$user user already exists"
383 else
384 echo "Creating $user user"
385 uids=$(dscl . -list /Users UniqueID|awk '{print $2}')
386 uid=$(pick $uids)
387 echo "(picked uid $uid)"
388 gid=$(dscl . -read /Groups/$group PrimaryGroupID | awk '{print $2}')
389 dscl . -create /Users/$user
390 dscl . -create /Users/$user UniqueID $uid
391 dscl . -create /Users/$user UserShell /usr/bin/false
392 dscl . -create /Users/$user RealName 'DisOrder server'
393 dscl . -create /Users/$user NFSHomeDirectory pkgstatedir
394 dscl . -create /Users/$user PrimaryGroupID $gid
395 dscl . -create /Users/$user Password \*
396 fi
397 ;;
398 FreeBSD )
399 # FreeBSD has a simple well-documented interface
400 if pw groupshow $group >/dev/null 2>&1; then
401 echo "$group group already exists"
402 else
403 echo "Creating $group group"
404 pw groupadd $group
405 fi
406 if pw usershow $user >/dev/null 2>&1; then
407 echo "$user user already exists"
408 else
409 echo "Creating $user user"
410 pw useradd $user -w no -d pkgstatedir -g $group -c 'DisOrder user'
411 fi
412 ;;
413 Linux )
414 if grep ^$group: /etc/group >/dev/null; then
415 echo "$group group already exists"
416 else
417 echo "Creating $group group"
418 groupadd $group
419 fi
420 if grep ^$user: /etc/passwd >/dev/null; then
421 echo "$user user already exists"
422 else
423 echo "Creating $user user"
424 useradd -d pkgstatedir -g $group $user -c 'DisOrder user'
425 fi
426 ;;
427 esac
428
429 echo "Making sure that pkgstatedir exists"
430 mkdir -p pkgstatedir
431 chown $user:$group pkgstatedir
432 chmod 2755 pkgstatedir
433
434 case $os in
435 Mac )
436 echo "Installing the plist into /Library/LaunchDaemons"
437 cp examples/uk.org.greenend.rjk.disorder.plist /Library/LaunchDaemons/.
438 echo "Reloading launchd"
439 launchctl load /Library/LaunchDaemons
440 echo "Starting DisOrder server"
441 launchctl start uk.org.greenend.rjk.disorder
442 CGIBIN=/Library/WebServer/CGI-Executables
443 DOCROOT=/Library/WebServer/Documents
444 sever_running=true
445 ;;
446 FreeBSD )
447 echo "Installing startup script into /etc/rc.d"
448 install -m 555 examples/disorder.rc /etc/rc.d/disorder
449 echo "Starting DisOrder server"
450 /etc/rc.d/disorder start
451 echo "Identifying web server"
452 set /usr/local/www/*
453 case $# in
454 0 )
455 echo
456 echo "Could not find a web server"
457 exit 1
458 ;;
459 1 )
460 ;;
461 * )
462 echo
463 echo "Yikes! There seems to be more than one web server here."
464 echo "Guessing that you want $1."
465 echo
466 ;;
467 esac
468 web=$1
469 echo "Found $web"
470 CGIBIN=$web/cgi-bin
471 DOCROOT=$web/data
472 server_running=true
473 ;;
474 Linux )
475 echo "Looking for init scripts directory"
476 for d in /etc/rc.d /etc; do
477 if [ -d $d/init.d ]; then
478 RC_D=$d
479 break
480 fi
481 done
482 if [ -z "$RC_D" ]; then
483 echo "Cannot find your init scripts directory"
484 else
485 echo "Installing init script into $RC_D/init.d"
486 install -m 755 examples/disorder.init $RC_D/init.d/disorder
487 echo "Linking init script into $RC_D/rc*.d"
488 for n in 2 3 4 5; do
489 echo " $RC_D/rc$n.d/S99disorder -> $RC_D/init.d/disorder"
490 rm -f $RC_D/rc$n.d/S99disorder
491 ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/S99disorder
492 done
493 for n in 0 1 6; do
494 echo " $RC_D/rc$n.d/K01disorder -> $RC_D/init.d/disorder"
495 rm -f $RC_D/rc$n.d/K01disorder
496 ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/K01disorder
497 done
498 echo "Starting DisOrder server"
499 $RC_D/init.d/disorder start
500 fi
501 echo "Looking for web server document root"
502 for d in /var/www/html /var/www; do
503 if [ -d $d ]; then
504 DOCROOT=$d
505 break
506 fi
507 done
508 echo "Looking for cgi-bin directory"
509 for d in /var/www/cgi-bin /usr/lib/cgi-bin; do
510 if [ -d $d ]; then
511 CGIBIN=$d
512 break
513 fi
514 done
515 server_running=true
516 ;;
517 * )
518 echo
519 echo "Sorry, I don't know how to install the server on this platform."
520 echo "You will have to do that by hand."
521 server_running=false
522 ;;
523 esac
524
525 echo
526 if [ -z "$DOCROOT" ]; then
527 echo "Cannot find your web server's document root"
528 else
529 echo "Setting up link to CGI's dependencies in $DOCROOT"
530 rm -f $DOCROOT/disorder
531 ln -s pkgdatadir/static $DOCROOT/disorder
532 fi
533
534 echo
535 if [ -z "$CGIBIN" ]; then
536 echo "Cannot find your web server's cgi-bin directory"
537 else
538 echo "Installing CGI in $CGIBIN"
539 install -m 555 server/disorder.cgi $CGIBIN/disorder
540 fi
541
542 if $server_running; then
543 first=true
544 sleep 5
545 while ! disorder version >/dev/null 2>&1; do
546 if $first; then
547 echo "Waiting for server startup to complete..."
548 first=false
549 fi
550 sleep 1
551 done
552 if [ $register = y ]; then
553 echo "Creating guest user with 'register' right"
554 disorder setup-guest
555 else
556 echo "Creating guest user without 'register' right"
557 disorder setup-guest --no-online-registration
558 fi
559 fi
560
561 echo
562 echo Done