tazpkg annotate tazpkg @ rev 972

Remove ashism ==
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Feb 26 08:21:22 2019 +0100 (2019-02-26)
parents 78e434868b22
children
rev   line source
pankso@6 1 #!/bin/sh
pankso@646 2 #
al@795 3 # TazPkg - Tiny autonomous zone packages manager.
pankso@6 4 #
paul@662 5 # This is a lightweight packages manager for *.tazpkg files written in SHell
al@795 6 # script. It works well with Busybox ash shell and bash. TazPkg lets you
pankso@646 7 # list, install, remove, download or get information about a package. You
pankso@646 8 # can use 'tazpkg usage' to get a list of commands with short descriptions.
al@795 9 # TazPkg also resolves dependencies and can upgrade packages from a mirror.
pankso@6 10 #
al@757 11 # (C) 2007-2015 SliTaz - GNU General Public License v3.
pankso@6 12 #
al@633 13 # Authors: See the AUTHORS files
pankso@27 14 #
pankso@6 15
al@795 16
pankso@6 17 ####################
pankso@6 18 # Script variables #
pankso@6 19 ####################
pankso@6 20
slaxemulator@588 21 . /etc/slitaz/slitaz.conf
pankso@307 22 . /etc/slitaz/tazpkg.conf
pankso@6 23
pankso@590 24 . /lib/libtaz.sh
pankso@661 25 . /usr/lib/slitaz/libpkg.sh
al@825 26 . @@MODULES@@/find-depends
pankso@590 27
pankso@595 28 # Internationalization.
al@694 29 export TEXTDOMAIN='tazpkg'
al@707 30 _() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; echo; }
al@707 31 _n() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; }
al@707 32 _p() {
al@811 33 local S="$1" P="$2" N="$3"; shift 3;
al@707 34 printf "$(ngettext "$S" "$P" "$N")" "$@"; }
al@694 35
pankso@343 36
al@834 37
al@834 38
al@834 39 # Remove all --parameters from cmdline
al@834 40 #-------------------------------------
al@834 41 # (thanks to libtaz.sh all --parameters are already set to variables)
al@834 42
al@834 43 IFS=$'\n'
al@834 44 set -- $(echo "$*" | sed '/^--/d')
al@834 45 unset IFS
al@834 46
al@834 47
pankso@307 48 # Initialize some variables to use words rather than numbers for functions
pankso@307 49 # and actions.
al@804 50
al@804 51 COMMAND="$1"
al@804 52 PACKAGE="${2%/}"
al@812 53 PACKAGE_DIR="$(cd $(dirname "$PACKAGE" 2>/dev/null) 2>/dev/null; pwd)"
al@694 54 [ -n "$PACKAGE" ] && PACKAGE_FILE="$PACKAGE_DIR/${PACKAGE##*/}"
pascal@427 55 if [ -f "$PACKAGE" ]; then
pankso@10 56 # Set pkg basename for install, extract
al@812 57 PACKAGE="$(basename "$PACKAGE" .tazpkg 2>/dev/null)"
pankso@10 58 else
pankso@10 59 # Pkg name for remove, search and all other cmds
al@804 60 PACKAGE="${PACKAGE%.tazpkg}"
pankso@10 61 fi
al@804 62 TARGET_DIR="$3"
al@840 63 export TOP_DIR="$(pwd)"
al@804 64 TMP_DIR="/tmp/$RANDOM"
al@804 65 INSTALL_LIST=''
gokhlayeh@419 66 SAVE_CACHE_DIR="$CACHE_DIR"
pankso@6 67
pankso@6 68 # Path to tazpkg used dir and configuration files
al@804 69 MIRROR="$PKGS_DB/mirror"
al@840 70 BLOCKED="$PKGS_DB/blocked-packages.list"
al@840 71 UP_LIST="$PKGS_DB/packages.up"
slaxemulator@588 72 DEFAULT_MIRROR="$ONLINE_PKGS"
pankso@6 73
al@811 74 # TazPkg version
al@844 75 export VERSION=$(awk -F$'\t' '$1=="tazpkg"{print $2}' "$PKGS_DB/installed.info")
al@811 76 # User Agent
al@836 77 export UA="TazPkg-$VERSION"
al@811 78
al@844 79
pascal@515 80
al@694 81
pankso@6 82 ####################
pankso@6 83 # Script functions #
pankso@6 84 ####################
pankso@6 85
al@694 86
al@717 87 # Interactive mode
al@717 88
al@717 89 im() { tty -s; }
al@717 90
al@717 91
al@844 92 # Show debug messages
al@846 93 debug() {
al@846 94 if [ -n "$debug" ]; then
al@846 95 colorize 036 "$@" >&2
al@846 96 echo -e "$(date +%f) $@" >> "${LOG/.log/.debug}"
al@846 97 fi
al@846 98 }
al@844 99
al@844 100
paul@662 101 # Check if dir exists
al@694 102
al@803 103 check_dir() {
al@811 104 if [ ! -d "$1" ]; then
al@707 105 action 'Creating folder "%s"...' "$1"
al@707 106 mkdir -p "$1"
pankso@584 107 status
pankso@584 108 return 1
pankso@584 109 fi
pankso@584 110 }
pankso@584 111
al@694 112
al@803 113 # Check if the directories and files used by TazPkg exist.
al@803 114 # If not and user is root we create them.
al@803 115
al@803 116 check_base_dir() {
pascal@972 117 if [ "$(id -u)" = '0' ]; then
pankso@590 118 check_dir $1$CACHE_DIR
pankso@590 119 check_dir $1$INSTALLED
pankso@594 120 check_dir $1$SLITAZ_LOGS
al@700 121 if [ ! -f "$1$PKGS_DB/mirror" ]; then
al@700 122 echo "${DEFAULT_MIRROR%/}/" > $1$PKGS_DB/mirror
al@700 123 [ -n "$1" ] && cp $PKGS_DB/packages.* $1$PKGS_DB/
pankso@590 124 fi
pankso@590 125 fi
pankso@590 126 }
pankso@590 127 check_base_dir
pankso@590 128
al@694 129
al@694 130
al@844 131
al@844 132 # Check commandline for tazpkg syntax
al@844 133
al@844 134 check_cmd() {
al@844 135 for i in $@; do
al@844 136 case $i in
al@844 137 su)
al@844 138 check_root "$COMMAND"; continue;;
al@844 139 pkg)
al@844 140 [ -n "$PACKAGE" -o -n "$list" ] && continue
al@844 141 newline; _ 'Please specify a package name on the command line.';;
al@844 142 list)
al@844 143 [ -n "$PACKAGE" ] && continue
al@844 144 newline; _ 'Please specify a list name on the command line.';;
al@844 145 flavor)
al@844 146 [ -n "$PACKAGE" ] && continue
al@844 147 newline; _ 'Please specify a flavor name on the command line.';;
al@844 148 release)
al@844 149 [ -n "$PACKAGE" ] && continue
al@844 150 newline; _ 'Please specify a release name on the command line.';;
al@844 151 file)
al@844 152 [ -f "$PACKAGE_FILE" ] && continue
al@844 153 newline; _ 'Unable to find file "%s"' "$PACKAGE_FILE";;
al@844 154 dir)
al@844 155 [ -d "$TARGET_DIR" ] && continue
al@844 156 newline; _ 'Please specify an existing folder name on the command line.';;
al@844 157 pattern)
al@844 158 [ -n "$PACKAGE" ] && continue
al@844 159 newline; _ 'Please specify a pattern to search for.';;
al@844 160 receipt)
al@844 161 [ -f "$INSTALLED/$PACKAGE/receipt" ] && continue
al@844 162 newline; _ 'Unable to find the receipt "%s"' "$INSTALLED/$PACKAGE/receipt";;
al@844 163 esac
al@844 164 tazpkg -h "$COMMAND"
al@707 165 exit 1
al@842 166 done
gokhlayeh@386 167 }
gokhlayeh@386 168
al@694 169
al@844 170 # List support for getting/installing packages listed in the file
al@844 171 process_list() {
al@844 172 debug "\nprocess_list()\n list='$list'"
al@844 173 local tmp_list pkg
al@694 174
al@844 175 [ -z "$list" ] && return
al@844 176
al@844 177 tmp_list="$(mktemp)"
al@844 178 cp "$list" "$tmp_list"
al@844 179 debug " tmp_list='$tmp_list'"
al@844 180
al@844 181 # Upgrade tazpkg first. It may handle new features/formats...
al@844 182 # then upgrade essential packages early
al@844 183 debug ' process important packages...'
al@844 184 for pkg in busybox-pam busybox gcc-lib-base glibc-base slitaz-base-files tazpkg; do
al@844 185 debug " pkg='$pkg'"
al@844 186 pkg=$(grep "^$pkg" "$tmp_list")
al@844 187 [ -z "$pkg" ] && continue
al@844 188 # Specify here empty list to prevent looping while recursive calls
al@844 189 debug " tazpkg $COMMAND '$pkg' --list=''"
al@844 190 tazpkg $COMMAND "$pkg" --list=''
al@844 191 sed -i "/^$pkg$/d" "$tmp_list"
al@844 192 done
al@844 193
al@844 194 # Process the rest of the list
al@844 195 debug ' process the rest...'
al@844 196 for pkg in $(cat "$tmp_list"); do
al@844 197 debug "tazpkg $COMMAND '$pkg' --list=''"
al@844 198 tazpkg $COMMAND "$pkg" --list=''
al@844 199 done
al@844 200
al@844 201 # Clean
al@844 202 rm "$tmp_list"
al@844 203 debug ' END: process_list()'
pascal@110 204 }
pascal@110 205
al@694 206
al@694 207
pascal@110 208
al@844 209 # Shared functions
al@844 210 # ----------------
al@694 211
al@844 212 # Log TazPkg activity
al@694 213
al@803 214 log_pkg() {
pascal@207 215 local extra
al@694 216
pascal@972 217 [ "$1" = 'Installed' ] && \
al@827 218 extra=" - $(fgrep " $PACKAGE-$VERSION" $PKGS_DB/installed.$SUM | awk '{ print $1 }')"
al@694 219
al@804 220 [ -e "$LOG" ] || touch $LOG
al@804 221
al@804 222 [ -w "$LOG" ] &&
al@694 223 echo "$(date +'%F %T') - $1 - $PACKAGE ($VERSION$EXTRAVERSION)$extra" >> $LOG
pascal@183 224 }
pascal@183 225
al@694 226
pascal@297 227 # Extract a package with cpio and gzip/lzma.
al@694 228
al@803 229 extract_package() {
al@702 230 action 'Extracting package...'
pascal@960 231 cpio -idm --quiet < "${PACKAGE_FILE##*/}" && rm -f "${PACKAGE_FILE##*/}"
pascal@297 232 if [ -f fs.cpio.lzma ]; then
pascal@960 233 unlzma < fs.cpio.lzma | cpio -idm --quiet && rm fs.cpio.lzma
gokhlayeh@355 234 elif [ -f fs.cpio.gz ]; then
pascal@960 235 zcat fs.cpio.gz | cpio -idm --quiet && rm fs.cpio.gz
pascal@297 236 fi
al@814 237 status
pankso@6 238 }
pankso@6 239
al@694 240
al@844 241 # Translate category names (must be last in line)
pankso@598 242
al@844 243 translate_category() {
al@844 244 sed "s|base-system$|$(_ base-system)|g; s|x-window$|$(_ x-window)|g;
al@844 245 s|utilities$|$(_ utilities)|g; s|network$|$(_ network)|g;
al@844 246 s|graphics$|$(_ graphics)|g; s|multimedia$|$(_ multimedia)|g;
al@844 247 s|office$|$(_ office)|g; s|development$|$(_ development)|g;
al@844 248 s|system-tools$|$(_ system-tools)|g; s|security$|$(_ security)|g;
al@844 249 s|games$|$(_ games)|g; s|misc$|$(_ misc)|g; s|meta$|$(_ meta)|g;
al@844 250 s|non-free$|$(_ non-free)|g"
pascal@299 251 }
pascal@299 252
al@694 253
al@844 254 # If category is not one of those translated in native language, keep it
al@844 255 # untranslated. This allows both native and English language support.
al@844 256 # This also supports custom categories.
al@844 257 # And now we support spaces in translated categories
al@844 258
al@844 259 reverse_translate_category() {
al@844 260 echo "$cat_i18n" | awk "BEGIN{FS=\" \"}{if (/^$@ /) a=\$2}END{if (a==\"\") a=\"$@\"; print a}"
pascal@377 261 }
pascal@377 262
al@844 263 # END: Shared functions
slaxemulator@588 264
al@694 265
al@694 266
al@694 267
pankso@6 268 ###################
al@803 269 # TazPkg commands #
pankso@6 270 ###################
pankso@6 271
pankso@6 272 case "$COMMAND" in
al@842 273 call)
al@842 274 # Call internal tazpkg function from external tazpkg module or other script.
al@842 275 # Useful for functions sharing.
al@842 276 shift
al@842 277 # Check to call only tazpkg functions
al@842 278 fgrep -q "$1()" "$0" && $@
al@842 279 ;;
al@842 280
al@842 281
pankso@504 282 list|-l)
al@828 283 # Various lists
al@603 284 shift
al@701 285 case $1 in
al@844 286 b|blocked) @@MODULES@@/list blocked;;
al@828 287 c|cat|categories) @@MODULES@@/list categories;;
al@844 288 l|linked) @@MODULES@@/list linked;;
al@844 289 '') @@MODULES@@/list installed;;
al@840 290 *) @@MODULES@@/list installed_of_category "$@";;
pankso@53 291 esac
al@603 292 ;;
al@844 293 -lb) @@MODULES@@/list blocked;;
al@828 294 -lc) @@MODULES@@/list categories;;
al@844 295 -ll) @@MODULES@@/list linked;;
al@828 296
al@844 297 -lm|list-mirror) @@MODULES@@/list mirrored;;
al@844 298 -lf|list-files) check_cmd pkg; @@MODULES@@/list installed_files "$PACKAGE";;
al@844 299 -a|activity|log) @@MODULES@@/list activity;;
al@844 300 list-config) @@MODULES@@/list config_files "$2";;
al@844 301 list-suggested) @@MODULES@@/list suggested;;
al@828 302
al@828 303
al@844 304 # Information about package
al@828 305 info)
al@844 306 check_cmd pkg; @@MODULES@@/info "$2";;
al@694 307
al@694 308
al@811 309 desc|-d)
al@717 310 # Display package description
al@844 311 check_cmd pkg; @@MODULES@@/description "$2";;
al@694 312
al@694 313
al@905 314 search|-s|-si|-sl)
pankso@6 315 # Search for a package by pattern or name.
al@844 316 check_cmd pattern
al@834 317
al@840 318 # Extend short options to long analogs
al@844 319 for i in $@; do
al@844 320 case "$i" in
al@844 321 -i|-si) export installed='yes';;
al@844 322 -l|-sl) export list='yes';;
al@905 323 -m) export mirror='yes';;
al@844 324 esac
al@844 325 done
al@834 326
al@840 327 @@MODULES@@/search pkg "$2"
al@834 328 ;;
al@694 329
al@694 330
pankso@593 331 search-file|-sf)
pankso@12 332 # Search for a file by pattern or name in all files.list.
al@844 333 check_cmd pattern; @@MODULES@@/search file "$2";;
al@694 334
al@694 335
al@811 336 search-pkgname|-sp)
pankso@344 337 # Search for a package name
al@844 338 check_cmd pattern; @@MODULES@@/search file2 "$2";;
al@694 339
al@694 340
pankso@76 341 add-flavor)
pascal@74 342 # Install a set of packages from a flavor.
al@844 343 check_cmd su flavor; shift; @@MODULES@@/flavor $@;;
pankso@76 344 install-flavor)
pascal@74 345 # Install a set of packages from a flavor and purge other ones.
al@844 346 check_cmd su flavor; shift; purge='yes' @@MODULES@@/flavor $@;;
al@694 347
al@694 348
pankso@76 349 set-release)
paul@662 350 # Change current release and upgrade packages.
al@844 351 check_cmd su release
al@844 352 @@MODULES@@/set-release "$2";;
al@694 353
al@694 354
pankso@504 355 remove|-r)
pankso@6 356 # Remove packages.
al@844 357 check_cmd su pkg; shift; @@MODULES@@/remove $@;;
al@844 358 # TODO: remove multiple packages
al@694 359
al@694 360
pankso@600 361 extract|-e)
pankso@6 362 # Extract .tazpkg cpio archive into a directory.
al@844 363 check_cmd pkg file; shift; @@MODULES@@/extract $@;;
al@694 364
al@694 365
pascal@297 366 recompress)
pascal@297 367 # Recompress .tazpkg cpio archive with lzma.
al@844 368 check_cmd su pkg file; @@MODULES@@/recompress "$PACKAGE_FILE";;
al@694 369
al@694 370
pascal@139 371 repack-config)
pascal@137 372 # Create SliTaz package archive from configuration files.
al@844 373 check_cmd su; @@MODULES@@/repack-config;;
al@694 374
al@694 375
pascal@18 376 repack)
MikeDSmith25@135 377 # Create SliTaz package archive from an installed package.
al@844 378 check_cmd pkg receipt; shift; @@MODULES@@/repack $@;;
al@694 379
al@694 380
pankso@6 381 pack)
pankso@600 382 # Create SliTaz package archive using cpio and lzma.
paul@943 383 # TODO: Cook also packs packages, we should share code in libpkg.sh
al@844 384 check_cmd pkg; shift; @@MODULES@@/pack $@;;
al@694 385
al@694 386
pankso@6 387 recharge)
al@803 388 # Recharge packages databases from a mirror.
pankso@581 389 #
al@694 390 # WARNING: The 'mirrors' file has all SliTaz mirrors but 'mirror'
paul@607 391 # must have only the chosen main mirror.
pankso@581 392 #
al@844 393 check_cmd su; shift; @@MODULES@@/recharge $@;;
al@694 394
al@694 395
al@603 396 up|upgrade)
paul@476 397 # This is the new way to upgrade packages making 'upgrade' and
pankso@466 398 # upgradeable out-of-date. This new way is much, much more faster!
paul@476 399 # Look into installed packages and get data from receipt, it is fast
paul@476 400 # and easy to handle vars after using only md5sum to compare packages
pankso@598 401 #
al@844 402 check_cmd su
al@691 403 for opt in $@; do
pankso@466 404 case "$opt" in
al@836 405 -i) export install='yes';;
al@836 406 -c) export check='yes';;
pankso@466 407 esac
pankso@466 408 done
al@834 409
al@836 410 @@MODULES@@/upgrade
al@834 411 ;;
al@694 412
al@694 413
pascal@152 414 bugs)
pascal@152 415 # Show known bugs in package(s)
al@844 416 shift; @@MODULES@@/bugs $@;;
al@694 417
al@694 418
pascal@25 419 check)
MikeDSmith25@135 420 # Check installed packages set.
al@844 421 shift; @@MODULES@@/check $@;;
pankso@598 422
pankso@598 423
al@840 424 block|-b|unblock|-u|chblock)
al@840 425 # Add/remove a pkg name to the list of blocked packages.
al@844 426 check_cmd su pkg; @@MODULES@@/block $@;;
al@694 427
al@694 428
al@785 429 get|-g)
al@603 430 # Download a package with wget.
al@844 431 check_cmd pkg; shift
al@844 432 # Get all the packages given on command line
al@844 433 export nocache='yes'
al@844 434 for i in $@; do
al@844 435 pkg="$(@@MODULES@@/get $i)" && _ 'Done: %s' "${pkg##*/}"
al@844 436 done
al@844 437 # Get all the packages listed in the file
al@844 438 process_list
al@844 439 ;;
pankso@598 440
pankso@598 441
al@844 442 install|-i)
al@844 443 # Install .tazpkg packages.
al@844 444 check_cmd su pkg file; shift
al@844 445 for i in $@; do
al@844 446 @@MODULES@@/install $i
al@844 447 done
al@844 448 # Install all the packages listed in the file
al@844 449 process_list
al@811 450 ;;
al@694 451
al@694 452
pankso@504 453 get-install|-gi)
pankso@6 454 # Download and install a package.
al@844 455 check_cmd su pkg; shift
al@864 456 export tazpkg_command='get-install'
al@844 457 # Get and install all the packages given on command line
al@844 458 for i in $@; do
al@844 459 pkg="$(@@MODULES@@/get $i)" && @@MODULES@@/install "$pkg"
al@844 460 done
al@844 461 # Get and install all the packages listed in the file
al@844 462 process_list
al@844 463 ;;
pankso@598 464
al@811 465
al@844 466 get-list|install-list|get-install-list)
al@844 467 # Install a set of packages from a list.
al@844 468 check_cmd su list file
al@844 469 COMMAND=${COMMAND%-list}
al@844 470 export list="$2"
al@844 471 process_list
al@844 472 ;;
al@694 473
al@694 474
pankso@504 475 clean-cache|-cc)
pankso@6 476 # Remove all downloaded packages.
al@844 477 check_cmd su; @@MODULES@@/cache clean;;
al@866 478 list-cache)
al@866 479 # List of packages in the cache.
al@866 480 @@MODULES@@/cache list;;
al@694 481
al@694 482
pascal@187 483 list-undigest)
al@840 484 # List undigest mirrors
al@844 485 @@MODULES@@/mirror list;;
pascal@187 486 remove-undigest)
al@840 487 # Remove undigest mirror
al@844 488 check_cmd su; shift; @@MODULES@@/mirror remove $@;;
al@840 489 add-undigest|setup-undigest)
al@840 490 # Add undigest mirror
al@844 491 check_cmd su; shift; @@MODULES@@/mirror add $@;;
al@840 492 setup-mirror|-sm)
al@840 493 # Change main mirror
al@844 494 check_cmd su; shift; @@MODULES@@/mirror setup $@;;
al@694 495
al@694 496
erjo@56 497 reconfigure)
erjo@56 498 # Replay post_install from receipt
al@844 499 check_cmd su pkg receipt; @@MODULES@@/reconfigure "$2";;
al@694 500
al@694 501
pankso@55 502 shell)
al@811 503 # TazPkg SHell
al@811 504 if [ "$(id -u)" -eq 0 ]; then
pankso@55 505 PROMPT="\\033[1;33mtazpkg\\033[0;39m# "
pankso@55 506 else
pankso@55 507 PROMPT="\\033[1;33mtazpkg\\033[0;39m> "
pankso@55 508 fi
al@834 509 if [ -z "$noheader" ]; then
pankso@55 510 clear
al@811 511 title 'TazPkg SHell.'
al@694 512 _ "Type 'usage' to list all available commands or 'quit' or 'q' to exit."
pankso@600 513 newline
pankso@55 514 fi
al@694 515 while true; do
pankso@55 516 echo -en "$PROMPT"; read cmd
pankso@55 517 case $cmd in
pankso@55 518 q|quit)
pankso@55 519 break ;;
pankso@55 520 shell)
al@811 521 _ 'You are already running a TazPkg SHell.' ;;
pankso@55 522 su)
pankso@55 523 su -c 'exec tazpkg shell --noheader' && break ;;
pankso@55 524 "")
pankso@55 525 continue ;;
pankso@55 526 *)
pankso@55 527 tazpkg $cmd ;;
pankso@55 528 esac
pankso@309 529 done ;;
al@694 530
al@694 531
pascal@205 532 depends)
paul@247 533 # Display dependencies tree
al@844 534 check_cmd pkg; shift; @@MODULES@@/depends depends $@;;
pascal@205 535 rdepends)
paul@247 536 # Display reverse dependencies tree
al@844 537 check_cmd pkg; shift; @@MODULES@@/depends rdepends $@;;
al@694 538
al@694 539
pankso@504 540 convert|-c)
pascal@262 541 # convert misc package format to .tazpkg
al@844 542 check_cmd file; shift; @@MODULES@@/convert $@;;
al@694 543
al@694 544
pascal@263 545 link)
al@840 546 # link a package from another SliTaz installation
al@844 547 check_cmd su pkg dir; shift; @@MODULES@@/link $@;;
al@694 548
al@694 549
al@811 550 help|-h)
al@811 551 # TazPkg help system
al@840 552 shift; @@MODULES@@/help $@
al@840 553 ;;
al@811 554
al@811 555
al@824 556 mkdb)
al@824 557 # Make TazPkg database
al@840 558 shift; @@MODULES@@/mkdb $@
al@840 559 ;;
al@824 560
al@824 561
al@820 562 '')
al@820 563 # Default to summary
al@840 564 @@MODULES@@/summary
al@820 565 ;;
al@820 566
al@820 567
pankso@6 568 usage|*)
pascal@119 569 # Print a short help or give usage for an unknown or empty command.
al@844 570 @@MODULES@@/help
al@844 571 ;;
pankso@6 572 esac
pankso@6 573
pankso@6 574 exit 0