View difference between Paste ID: vX4WCDvm and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | #! /bin/sh |
2 | ### BEGIN INIT INFO | |
3 | # Provides: minecraft_server | |
4 | # Required-Start: $remote_fs $syslog | |
5 | # Required-Stop: $remote_fs $syslog | |
6 | # Default-Start: 2 3 4 5 | |
7 | # Default-Stop: 0 1 6 | |
8 | # Short-Description: Minecraft Server control script. | |
9 | # Description: Minecraft Server control script. | |
10 | # Options | |
11 | # start <world> - Start the Minecraft world server. Starts all world servers by default. | |
12 | # stop <world> - Stop the Minecraft world server. Stops all world servers by default. | |
13 | # force-stop <world> - Forcibly stop the Minecraft world server. Forcibly stops all world servers by default. | |
14 | # restart <world> - Restart the Minecraft world server. Restarts all world servers by default. | |
15 | # force-restart <world> - Forcibly restart the Minecraft world server. Forcibly restarts all world servers by default. | |
16 | # status <world> - Display the status of the Minecraft world server. Displays the status of all world servers by default. | |
17 | # send <world> <command> - Send a command to a Minecraft world server. | |
18 | # backup <world> - Backup the Minecraft world. Backup all worlds by default. | |
19 | # c10t <world> - Run the c10t mapping software on the Minecraft world. Maps all worlds by default. | |
20 | # update <software> - Update a software package. Update the server software and all addons by default. | |
21 | # Available software options | |
22 | # server - Minecraft server software. | |
23 | # c10t - Mapping software. | |
24 | ### END INIT INFO | |
25 | ||
26 | ||
27 | USER_NAME=minecraft | |
28 | ||
29 | LOCATION="/home/$USER_NAME" | |
30 | ||
31 | ||
32 | ## Minecraft software options. | |
33 | ||
34 | # Software packages, used for updating. | |
35 | PACKAGES="server c10t" | |
36 | ||
37 | # Minecraft server. | |
38 | SERVER_URL="http://www.minecraft.net/download/minecraft_server.jar" | |
39 | SERVER_LOCATION="$LOCATION/minecraft_server" | |
40 | SERVER_JAR="$SERVER_LOCATION/minecraft_server.jar" | |
41 | SERVER_ARGS="nogui" | |
42 | INITIAL_MEMORY="1024M" | |
43 | MAXIMUM_MEMORY="1024M" | |
44 | ||
45 | # c10t mapping software. | |
46 | ARCH=$(uname -m) | |
47 | C10T_URL="http://toolchain.eu/hudson/job/c10t%20HEAD%20Linux%20$ARCH/lastStableBuild/artifact/build/c10t-HEAD-linux-$ARCH.tar.gz" | |
48 | C10T_LOCATION="$LOCATION/c10t" | |
49 | C10T_BIN="$C10T_LOCATION/c10t" | |
50 | ||
51 | # Location to place map images, and the URL displayed to users for map access. | |
52 | MAPS_URL="http://minecraft.server.com/maps" | |
53 | MAPS_LOCATION="$LOCATION/maps" | |
54 | ||
55 | ||
56 | ## World configuration. | |
57 | ||
58 | WORLDS_LOCATION="$LOCATION/worlds" | |
59 | ||
60 | # List of worlds and the ports they are running on. This file will | |
61 | # be generated if missing. | |
62 | # Note: World name should not contain a space, at least for now. | |
63 | # ie: | |
64 | # alpha 25565 | |
65 | # beta 25566 | |
66 | WORLDS_CONF="$LOCATION/worlds.conf" | |
67 | ||
68 | # Default world name and port if worlds.conf is missing. | |
69 | DEFAULT_WORLD="world" | |
70 | DEFAULT_PORT="25565" | |
71 | ||
72 | ||
73 | ## Backup configuration. | |
74 | ||
75 | BACKUP_LOCATION="$LOCATION/backups" | |
76 | ||
77 | # Length in days that backups survive. | |
78 | BACKUP_FULL_DURATION=31 | |
79 | ||
80 | ||
81 | ## Internal Methods. | |
82 | ||
83 | getProcessIDs() { | |
84 | # Get the PIDs of the Screen and Java process for the world server. | |
85 | # ARGS: world | |
86 | local SCREEN_PID JAVA_PID | |
87 | SCREEN_PID=$(su -c "$SCREEN -ls" $USER_NAME | $PERL -ne 'if ($_ =~ /^\t(\d+)\.minecraft-'$1'/) { print $1; }') | |
88 | JAVA_PID=$(ps -a -u $USER_NAME -o pid,ppid,comm | $PERL -ne 'if ($_ =~ /^\s*(\d+)\s+'$SCREEN_PID'\s+java/) { print $1; }') | |
89 | echo "$SCREEN_PID $JAVA_PID" | |
90 | } | |
91 | ||
92 | serverRunning() { | |
93 | # Check to see if the world server is running. | |
94 | # ARGS: world | |
95 | local PIDS | |
96 | PIDS=$(getProcessIDs $1) | |
97 | # Try to determine if the world is running. | |
98 | if [ -n "$(echo $PIDS | cut -d ' ' -f1)" ] && [ -n "$(echo $PIDS | cut -d ' ' -f2)" ]; then | |
99 | echo 1 | |
100 | else | |
101 | echo 0 | |
102 | fi | |
103 | } | |
104 | ||
105 | sendCommand() { | |
106 | # Send a command to the world server. | |
107 | # ARGS: world command | |
108 | local COMMAND | |
109 | COMMAND=$(printf "$2\r") | |
110 | su -c "$SCREEN -S minecraft-$1 -p 0 -X stuff \"$COMMAND\"" $USER_NAME | |
111 | if [ ! $? = 0 ]; then | |
112 | printf "Error sending command to server.\n" | |
113 | exit 1 | |
114 | fi | |
115 | ||
116 | } | |
117 | ||
118 | listContains() { | |
119 | # Check whether a list contains something that matches the pattern. | |
120 | # ARGS: pattern list | |
121 | local MATCH | |
122 | MATCH=$(echo \"$2\" | $PERL -ne 'if ($_ =~ /('$1')/) { print "$1"; }') | |
123 | if [ -n "$MATCH" ]; then | |
124 | echo 1 | |
125 | else | |
126 | echo 0 | |
127 | fi | |
128 | } | |
129 | ||
130 | start() { | |
131 | # Start the world server. | |
132 | # ARGS: world | |
133 | local SERVER_PORT | |
134 | # Make sure that the server directory exists. | |
135 | su -c "mkdir -p $WORLDS_LOCATION/$1" $USER_NAME | |
136 | cd $WORLDS_LOCATION/$1 | |
137 | # Make sure that the server properties file exists. | |
138 | if [ ! -e server.properties ]; then | |
139 | SERVER_PORT=$(grep $1 $WORLDS_CONF | cut -f2) | |
140 | su -c "printf \"# Minecraft server properties\n\" > server.properties" $USER_NAME | |
141 | su -c "printf \"level-name=world\n\" >> server.properties" $USER_NAME | |
142 | su -c "printf \"server-port=$SERVER_PORT\n\" >> server.properties" $USER_NAME | |
143 | fi | |
144 | # Start the server. | |
145 | su -c "$SCREEN -dmS minecraft-$1 $JAVA -Xms$INITIAL_MEMORY -Xmx$MAXIMUM_MEMORY -jar $SERVER_JAR $SERVER_ARGS" $USER_NAME | |
146 | if [ ! $? = 0 ]; then | |
147 | printf "Error starting the server.\n" | |
148 | exit 1 | |
149 | fi | |
150 | } | |
151 | ||
152 | forceStop() { | |
153 | # Forcibly stop the world server. | |
154 | # ARGS: world | |
155 | local PIDS | |
156 | PIDS=$(getProcessIDs $1) | |
157 | # Try to stop the server cleanly first. | |
158 | sendCommand $1 "stop" | |
159 | sleep 5 | |
160 | # Kill the process ids of the world server. | |
161 | kill -9 $PIDS > /dev/null 2>&1 | |
162 | } | |
163 | ||
164 | fullBackup() { | |
165 | # Backup the world server. | |
166 | # ARGS: world | |
167 | # Grab the date and time. | |
168 | local DATE_TIME | |
169 | DATE_TIME=$(date +%Y-%m-%d-%H:%M:%S) | |
170 | su -c "mkdir -p $BACKUP_LOCATION" $USER_NAME | |
171 | cd $WORLDS_LOCATION | |
172 | su -c "tar -czf $BACKUP_LOCATION/fullBackup-$1-$DATE_TIME.tar.gz $1" $USER_NAME | |
173 | # Cleanup old backups. | |
174 | su -c "find $BACKUP_LOCATION -name fullBackup-$1-* -type f -mtime +$BACKUP_FULL_DURATION -delete" $USER_NAME | |
175 | } | |
176 | ||
177 | update() { | |
178 | # Update software package. | |
179 | # ARGS: package | |
180 | case "$1" in | |
181 | server) | |
182 | su -c "mkdir -p $SERVER_LOCATION" $USER_NAME | |
183 | # Backup the old server jar. | |
184 | if [ -e $SERVER_JAR ]; then | |
185 | su -c "mv -f $SERVER_JAR $SERVER_JAR.old" $USER_NAME | |
186 | fi | |
187 | # Download the new server software. | |
188 | su -c "$WGET -qO $SERVER_JAR $SERVER_URL" $USER_NAME | |
189 | # Check for error and restore backup if found. | |
190 | if [ ! $? = 0 ]; then | |
191 | printf "Error updating server software.\n" | |
192 | if [ -e "$SERVER_JAR.old" ]; then | |
193 | su -c "mv -f $SERVER_JAR.old $SERVER_JAR" $USER_NAME | |
194 | fi | |
195 | exit 1 | |
196 | fi | |
197 | ;; | |
198 | c10t) | |
199 | su -c "mkdir -p $C10T_LOCATION" $USER_NAME | |
200 | # Download the new c10t mapping software. | |
201 | cd $C10T_LOCATION | |
202 | su -c "$WGET -qO c10t.tar.gz $C10T_URL" $USER_NAME | |
203 | if [ ! $? = 0 ]; then | |
204 | printf "Error updating c10t.\n" | |
205 | exit 1 | |
206 | fi | |
207 | su -c "tar xzf c10t.tar.gz" $USER_NAME | |
208 | su -c "cp -R c10t-HEAD/* ." $USER_NAME | |
209 | su -c "rm -R c10t-HEAD" $USER_NAME | |
210 | ;; | |
211 | *) | |
212 | printf "Unknown software package: $1\n" | |
213 | exit 1 | |
214 | ;; | |
215 | esac | |
216 | } | |
217 | ||
218 | c10t() { | |
219 | # Run c10t mapping software on the server. | |
220 | # ARGS: world | |
221 | su -c "mkdir -p $MAPS_LOCATION/$1" $USER_NAME | |
222 | # Make sure that the world files are actually there before mapping. | |
223 | if [ -e "$WORLDS_LOCATION/$1/server.properties" ]; then | |
224 | su -c "$C10T_BIN -s -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/surface.png" $USER_NAME | |
225 | su -c "$C10T_BIN -s -c -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves.png" $USER_NAME | |
226 | su -c "$C10T_BIN -s -c -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves_heightmap.png" $USER_NAME | |
227 | su -c "$C10T_BIN -s -a -i 56 -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/diamonds_heightmap.png" $USER_NAME | |
228 | su -c "$C10T_BIN -s -a -i 4 -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/cobble_heightmap.png" $USER_NAME | |
229 | su -c "$C10T_BIN -s -q -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/surface_oblique.png" $USER_NAME | |
230 | su -c "$C10T_BIN -s -q -c -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves_oblique.png" $USER_NAME | |
231 | fi | |
232 | } | |
233 | ||
234 | ## Begin. | |
235 | ||
236 | # Make sure that Java, Perl, GNU Screen, and GNU Wget are installed. | |
237 | JAVA=$(which java) | |
238 | PERL=$(which perl) | |
239 | SCREEN=$(which screen) | |
240 | WGET=$(which wget) | |
241 | if [ ! -e $JAVA ]; then | |
242 | printf "Java not found!\n" | |
243 | printf "Try installing this with:\n" | |
244 | printf "sudo apt-get install openjdk-6-jre\n" | |
245 | exit 1 | |
246 | fi | |
247 | if [ ! -e $PERL ]; then | |
248 | printf "Perl not found!\n" | |
249 | printf "Try installing this with:\n" | |
250 | printf "sudo apt-get install perl\n" | |
251 | exit 1 | |
252 | fi | |
253 | if [ ! -e $SCREEN ]; then | |
254 | printf "GNU Screen not found!\n" | |
255 | printf "Try installing this with:\n" | |
256 | printf "sudo apt-get install screen\n" | |
257 | exit 1 | |
258 | fi | |
259 | if [ ! -e $WGET ]; then | |
260 | printf "GNU Wget not found!\n" | |
261 | printf "Try installing this with:\n" | |
262 | printf "sudo apt-get install wget\n" | |
263 | exit 1 | |
264 | fi | |
265 | ||
266 | # Make sure that the minecraft user exists, print a sane error if not. | |
267 | if [ ! -n "$(grep $USER_NAME /etc/passwd)" ]; then | |
268 | printf "This script requires that a user account named $USER_NAME exist on this system.\n" | |
269 | printf "Try adding this user:\n" | |
270 | printf "sudo adduser $USER_NAME\n" | |
271 | exit 1 | |
272 | fi | |
273 | ||
274 | # From here on out the script needs to be run as root, print a sane error if running as a user. | |
275 | WHOAMI=$(whoami) | |
276 | if [ ! "$WHOAMI" = "root" ]; then | |
277 | printf "This script needs to be run as root, you seem to be $WHOAMI.\n" | |
278 | printf "Try running this with sudo:\n" | |
279 | printf "sudo $0 start\n" | |
280 | exit 1 | |
281 | fi | |
282 | ||
283 | # Make sure that the worlds.conf file exists. | |
284 | if [ ! -e $WORLDS_CONF ]; then | |
285 | su -c "printf \"$DEFAULT_WORLD\t$DEFAULT_PORT\n\" > $WORLDS_CONF" $USER_NAME | |
286 | fi | |
287 | ||
288 | # Grab the list of worlds. | |
289 | WORLDS=$(cut -f1 $WORLDS_CONF) | |
290 | ||
291 | # Respond to the command line arguments. | |
292 | case "$1" in | |
293 | start) | |
294 | printf "Starting Minecraft Server:" | |
295 | # Make sure that the server software exists. | |
296 | if [ ! -e $SERVER_JAR ]; then | |
297 | printf "Server software not found, downloading it...\n" | |
298 | update "server" | |
299 | fi | |
300 | # Check for the optional world command line argument. | |
301 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
302 | WORLDS="$2" | |
303 | elif [ -n "$2" ]; then | |
304 | printf "Minecraft world $2 not found!\n" | |
305 | printf " Usage: $0 $1 <world>\n" | |
306 | exit 1 | |
307 | fi | |
308 | # Start each world requested, if not already running. | |
309 | for WORLD in $WORLDS; do | |
310 | if [ $(serverRunning $WORLD) = 0 ]; then | |
311 | printf " $WORLD" | |
312 | start $WORLD | |
313 | fi | |
314 | done | |
315 | printf "\n" | |
316 | ;; | |
317 | stop|force-stop) | |
318 | printf "Stopping Minecraft Server:" | |
319 | # Check for the optional world command line argument. | |
320 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
321 | WORLDS="$2" | |
322 | elif [ -n "$2" ]; then | |
323 | printf "Minecraft world $2 not found!\n" | |
324 | printf " Usage: $0 $1 <world>\n" | |
325 | exit 1 | |
326 | fi | |
327 | # Stop each world requested, if running. | |
328 | for WORLD in $WORLDS; do | |
329 | # Try to stop the world cleanly. | |
330 | if [ $(serverRunning $WORLD) = 1 ]; then | |
331 | printf " $WORLD" | |
332 | sendCommand $WORLD "say The server is about to go down." | |
333 | sendCommand $WORLD "save-all" | |
334 | sendCommand $WORLD "save-off" | |
335 | sendCommand $WORLD "say The server is going down in 5 seconds..." | |
336 | sleep 5 | |
337 | if [ "$1" = "force-stop" ]; then | |
338 | forceStop $WORLD | |
339 | else | |
340 | sendCommand $WORLD "stop" | |
341 | fi | |
342 | sleep 5 | |
343 | fi | |
344 | done | |
345 | printf "\n" | |
346 | ;; | |
347 | restart|reload|force-restart|force-reload) | |
348 | printf "Restarting Minecraft Server:" | |
349 | # Check for the optional world command line argument. | |
350 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
351 | WORLDS="$2" | |
352 | elif [ -n "$2" ]; then | |
353 | printf "Minecraft world $2 not found!\n" | |
354 | printf " Usage: $0 $1 <world>\n" | |
355 | exit 1 | |
356 | fi | |
357 | # Restart each world requested, start those not already running. | |
358 | for WORLD in $WORLDS; do | |
359 | printf " $WORLD" | |
360 | if [ $(serverRunning $WORLD) = 1 ]; then | |
361 | sendCommand $WORLD "say The server is about to restart." | |
362 | sendCommand $WORLD "save-all" | |
363 | sendCommand $WORLD "save-off" | |
364 | sendCommand $WORLD "say Restarting in 5 seconds..." | |
365 | sleep 5 | |
366 | if [ "$(echo $1 | cut -d '-' -f1)" = "force" ]; then | |
367 | forceStop $WORLD | |
368 | else | |
369 | sendCommand $WORLD "stop" | |
370 | fi | |
371 | sleep 5 | |
372 | fi; | |
373 | start $WORLD | |
374 | done | |
375 | printf "\n" | |
376 | ;; | |
377 | status|show) | |
378 | printf "Minecraft Server Status:\n" | |
379 | # Check for the optional world command line argument. | |
380 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
381 | WORLDS="$2" | |
382 | elif [ -n "$2" ]; then | |
383 | printf "Minecraft world $2 not found!\n" | |
384 | printf " Usage: $0 $1 <world>\n" | |
385 | exit 1 | |
386 | fi | |
387 | # Show the status of each world requested. | |
388 | for WORLD in $WORLDS; do | |
389 | printf " $WORLD: " | |
390 | if [ $(serverRunning $WORLD) = 1 ]; then | |
391 | printf "running.\n" | |
392 | else | |
393 | printf "not running.\n" | |
394 | fi | |
395 | done | |
396 | ;; | |
397 | send) | |
398 | WORLD=$2 | |
399 | if [ -n "$WORLD" ] && [ $(listContains $WORLD "$WORLDS") = 1 ]; then | |
400 | shift 2 | |
401 | printf "Send command to world $WORLD: $*\n" | |
402 | sendCommand $WORLD "$*" | |
403 | else | |
404 | printf "Minecraft world $WORLD not found!\n" | |
405 | printf " Usage: $0 $1 <world> <command>\n" | |
406 | printf " ie: $0 $1 world say \"Hello World!\"\n" | |
407 | exit 1 | |
408 | fi | |
409 | ;; | |
410 | backup) | |
411 | printf "Backing up Minecraft Server:" | |
412 | # Check for the optional world command line argument. | |
413 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
414 | WORLDS="$2" | |
415 | elif [ -n "$2" ]; then | |
416 | printf "Minecraft world $2 not found!\n" | |
417 | printf " Usage: $0 $1 <world>\n" | |
418 | exit 1 | |
419 | fi | |
420 | # Backup each world requested. | |
421 | for WORLD in $WORLDS; do | |
422 | printf " $WORLD" | |
423 | if [ $(serverRunning $WORLD) = 1 ]; then | |
424 | sendCommand $WORLD "say Backing up the world." | |
425 | sendCommand $WORLD "save-all" | |
426 | sendCommand $WORLD "save-off" | |
427 | sleep 20 | |
428 | fullBackup $WORLD | |
429 | sendCommand $WORLD "save-on" | |
430 | sendCommand $WORLD "say Backup complete." | |
431 | else | |
432 | fullBackup $WORLD | |
433 | fi | |
434 | done | |
435 | printf "\n" | |
436 | ;; | |
437 | update) | |
438 | printf "Updating the Minecraft Server software...\n" | |
439 | # Check for the optional package command line argument. | |
440 | if [ -n "$2" ] && [ $(listContains $2 "$PACKAGES") = 1 ]; then | |
441 | PACKAGES="$2" | |
442 | elif [ -n "$2" ]; then | |
443 | printf "Minecraft software package $2 not found!\n" | |
444 | printf " Usage: $0 $1 <software package>\n" | |
445 | exit 1 | |
446 | fi | |
447 | if [ -n "$(echo $PACKAGES | grep server)" ]; then | |
448 | printf "Stopping Minecraft Server:" | |
449 | for WORLD in $WORLDS; do | |
450 | printf " $WORLD" | |
451 | if [ $(serverRunning $WORLD) = 1 ]; then | |
452 | sendCommand $WORLD "say The server software is being updated." | |
453 | sendCommand $WORLD "say Server restart is imminent." | |
454 | sendCommand $WORLD "save-all" | |
455 | sendCommand $WORLD "save-off" | |
456 | sleep 20 | |
457 | fullBackup $WORLD | |
458 | sendCommand $WORLD "say Restarting in 5 seconds." | |
459 | sleep 5 | |
460 | sendCommand $WORLD "stop" | |
461 | else | |
462 | fullBackup $WORLD | |
463 | fi | |
464 | done | |
465 | printf "\n" | |
466 | fi | |
467 | # Update each software package requested. | |
468 | printf "Updating software package:" | |
469 | for PACKAGE in $PACKAGES; do | |
470 | printf " $PACKAGE" | |
471 | update $PACKAGE | |
472 | done | |
473 | printf "\n" | |
474 | if [ -n "$(echo $PACKAGES | grep server)" ]; then | |
475 | printf "Starting Minecraft Server:" | |
476 | for WORLD in $WORLDS; do | |
477 | printf " $WORLD" | |
478 | start $WORLD | |
479 | done | |
480 | printf "\n" | |
481 | fi | |
482 | ;; | |
483 | c10t|map) | |
484 | # Make sure that the c10t software exists. | |
485 | if [ ! -e $C10T_BIN ]; then | |
486 | printf "c10t software not found, downloading it...\n" | |
487 | update "c10t" | |
488 | fi | |
489 | # Check for the optional world command line argument. | |
490 | if [ -n "$2" ] && [ $(listContains $2 "$WORLDS") = 1 ]; then | |
491 | WORLDS="$2" | |
492 | elif [ -n "$2" ]; then | |
493 | printf "Minecraft world $2 not found!\n" | |
494 | printf " Usage: $0 $1 <world>\n" | |
495 | exit 1 | |
496 | fi | |
497 | # Run c10t on each world requested. | |
498 | printf "Running c10t mapping:" | |
499 | for WORLD in $WORLDS; do | |
500 | printf " $WORLD" | |
501 | if [ $(serverRunning $WORLD) = 1 ]; then | |
502 | sendCommand $WORLD "say The world is about to be mapped with c10t." | |
503 | sendCommand $WORLD "save-all" | |
504 | sendCommand $WORLD "save-off" | |
505 | sleep 20 | |
506 | fullBackup $WORLD | |
507 | c10t $WORLD | |
508 | sendCommand $WORLD "save-on" | |
509 | sendCommand $WORLD "say Mapping is complete. You can access the maps at:" | |
510 | sendCommand $WORLD "say $MAPS_URL/$WORLD" | |
511 | else | |
512 | fullBackup $WORLD | |
513 | c10t $WORLD | |
514 | fi | |
515 | done | |
516 | printf "\n" | |
517 | ;; | |
518 | *) | |
519 | printf "Usage: $0 {start|stop|force-stop|restart|force-restart|status|send|backup|update|c10t} {Optional: world or software package}\n" | |
520 | exit 1 | |
521 | ;; | |
522 | esac | |
523 | exit 0 |