You need to sign in or sign up before continuing.
epm-sh-functions 22.8 KB
Newer Older
Vitaly Lipatov's avatar
Vitaly Lipatov committed
1 2
#!/bin/sh
#
3 4
# Copyright (C) 2012, 2014  Etersoft
# Copyright (C) 2012, 2014  Vitaly Lipatov <lav@etersoft.ru>
Vitaly Lipatov's avatar
Vitaly Lipatov committed
5
#
6 7 8
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Vitaly Lipatov's avatar
Vitaly Lipatov committed
9 10 11 12 13
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU Affero General Public License for more details.
Vitaly Lipatov's avatar
Vitaly Lipatov committed
15
#
16 17
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
Vitaly Lipatov's avatar
Vitaly Lipatov committed
18 19
#

20
# copied from /etc/init.d/outformat (ALT Linux)
21

22

23
# FIXME on Android: FIX ME! implement ttyname_r() bionic/libc/bionic/stubs.c:366
24 25
inputisatty()
{
26 27 28
    # check stdin
    #tty -s 2>/dev/null
    test -t 0
29 30
}

31 32
isatty()
{
33 34
    # check stdout
    test -t 1
35 36 37 38
}

isatty2()
{
39 40
    # check stderr
    test -t 2
41 42
}

43 44
check_tty()
{
45
    isatty2 || return
46

47 48 49
    # Set a sane TERM required for tput
    [ -n "$TERM" ] || TERM=dumb
    export TERM
50

51
    check_core_commands
52

53 54 55 56 57
    # grep -E from busybox may not --color
    # grep -E from MacOS print help to stderr
    if grep -E --help 2>&1 | grep -q -- "--color" ; then
        export EGREPCOLOR="--color"
    fi
58

59 60 61 62
    is_command tput || return
    # FreeBSD does not support tput -S
    echo | a= tput -S >/dev/null 2>/dev/null || return
    USETTY="tput -S"
63 64
}

65 66 67 68
: ${BLACK:=0} ${RED:=1} ${GREEN:=2} ${YELLOW:=3} ${BLUE:=4} ${MAGENTA:=5} ${CYAN:=6} ${WHITE:=7}

set_boldcolor()
{
69 70 71 72 73
    [ -n "$USETTY" ] || return
    {
        echo bold
        echo setaf $1
    } | $USETTY
74 75
}

76 77
set_color()
{
78 79 80 81
    [ -n "$USETTY" ] || return
    {
        echo setaf $1
    } | $USETTY
82 83
}

84 85
restore_color()
{
86 87 88 89 90
    [ -n "$USETTY" ] || return
    {
        echo op; # set Original color Pair.
        echo sgr0; # turn off all special graphics mode (bold in our case).
    } | $USETTY
91 92
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
93 94
echover()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
95
    [ -z "$verbose" ] && return
96
    echo "$*" >&2
Vitaly Lipatov's avatar
Vitaly Lipatov committed
97 98
}

99 100 101
# echo string without EOL
echon()
{
102 103
    # default /bin/sh on MacOS does not recognize -n
    echo -n "$*" 2>/dev/null || a= /bin/echo -n "$*"
104 105 106
}


Vitaly Lipatov's avatar
Vitaly Lipatov committed
107
# Print command line and run command line
108
showcmd()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
109
{
110 111 112 113 114 115 116
    if [ -z "$quiet" ] ; then
        set_boldcolor $GREEN
        local PROMTSIG="\$"
        is_root && PROMTSIG="#"
        echo " $PROMTSIG $*"
        restore_color
    fi >&2
117 118
}

119 120 121
# Print command
echocmd()
{
122 123 124 125 126
    set_boldcolor $GREEN
    local PROMTSIG="\$"
    is_root && PROMTSIG="#"
    echo -n "$PROMTSIG $*"
    restore_color
127 128
}

129 130 131
# Print command line and run command line
docmd()
{
132 133
    showcmd "$*$EXTRA_SHOWDOCMD"
    "$@"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
134 135
}

136
# Run every arg with docmd
137 138
docmd_foreach()
{
139 140 141 142 143 144 145
    local cmd pkg
    cmd="$1"
    #showcmd "$@"
    shift
    for pkg in "$@" ; do
        docmd $cmd $pkg
    done
146 147
}

148 149 150
# run command line with SUDO
sudorun()
{
151 152 153 154 155 156
    set_sudo
    if [ -z "$SUDO" ] ; then
        "$@"
        return
    fi
    $SUDO "$@"
157 158
}

159
# Print command line and run command line with SUDO
160
sudocmd()
161
{
162 163 164
    set_sudo
    [ -n "$SUDO" ] && showcmd "$SUDO $*" || showcmd "$*"
    sudorun "$@"
165 166
}

167
# Run every arg with sudocmd
168
# Returns on any error
169 170
sudocmd_foreach()
{
171 172 173 174 175 176 177 178
    local cmd pkg
    cmd="$1"
    #showcmd "$@"
    shift
    for pkg in "$@" ; do
        # don't quote $cmd here: it can be a command with an args
        sudocmd $cmd $pkg || return
    done
179 180
}

181 182 183
# print full path to files
make_filepath()
{
184 185 186 187 188 189
    local i
    for i in "$@" ; do
        [ -f "$i" ] || continue
        echo "$i" | grep -q "/" && echo "$i" && continue
        echo "./$i"
    done
190 191
}

192 193
get_firstarg()
{
194
    echon "$1"
195 196 197 198
}

get_lastarg()
{
199 200 201
    local lastarg
    eval "lastarg=\${$#}"
    echon "$lastarg"
202 203
}

204 205 206
# TODO: see etersoft-build-utils/tests/test_isnumber.sh
isnumber()
{
207
    echo "$*" | filter_strip_spaces | grep -q "^[0-9]\+$"
208 209
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
210 211
# copied from strings
# CHECKME: the same like estrlist has ?
Vitaly Lipatov's avatar
Vitaly Lipatov committed
212
# Note: used grep -E! write '[0-9]+(first|two)', not '[0-9]\+...'
Vitaly Lipatov's avatar
Vitaly Lipatov committed
213 214
rhas()
{
215
    echo "$1" | grep -E -q -- "$2"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
216 217
}

218 219 220 221 222 223 224 225 226 227 228 229 230
# bash specific
startwith()
{
    # rhas "$1" "^$2"
    [[ "$1" = ${2}* ]]
}

is_abs_path()
{
    #echo "$1" | grep -q "^/"
    startwith "$1" "/"
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
231 232 233 234
# copied from strings
is_dirpath()
{
    [ "$1" = "." ] && return $?
235 236
    # rhas "$1" "/"
    startwith "$1" "/"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
237 238
}

239

Vitaly Lipatov's avatar
Vitaly Lipatov committed
240 241 242 243 244 245 246 247 248 249 250 251 252
filter_strip_spaces()
{
        # possible use just
        #xargs echo
        sed -e "s| \+| |g" | \
                sed -e "s|^ ||" | sed -e "s| \$||"
}

strip_spaces()
{
        echo "$*" | filter_strip_spaces
}

253 254 255 256 257 258

# https://superuser.com/questions/422459/substitution-in-text-file-without-regular-expressions
# http://stackoverflow.com/a/2705678/120999
# use for subst complex string with symbols treating as regexp
sed_escape()
{
259
    echo "$*" | sed -e 's/[]()$*.^|[]/\\&/g'
260 261 262
}


263 264 265
# param true false
subst_option()
{
266
    eval "[ -n \"\$$1\" ]" && echo "$2" || echo "$3"
267 268
}

269 270 271
store_output()
{
    # use make_temp_file from etersoft-build-utils
272
    RC_STDOUT="$(mktemp)" || fatal
273
    remove_on_exit $RC_STDOUT
274 275
    local CMDSTATUS=$RC_STDOUT.pipestatus
    echo 1 >$CMDSTATUS
276
    #RC_STDERR=$(mktemp)
277
    ( LC_ALL=C $@ 2>&1 ; echo $? >$CMDSTATUS ) | tee $RC_STDOUT
Vitaly Lipatov's avatar
Vitaly Lipatov committed
278
    return "$(cat $CMDSTATUS)"
279
    # bashism
280
    # http://tldp.org/LDP/abs/html/bashver3.html#PIPEFAILREF
281
    #return $PIPESTATUS
282 283
}

284 285 286 287 288 289
showcmd_store_output()
{
    showcmd "$@"
    store_output "$@"
}

290 291
clean_store_output()
{
292
    rm -f $RC_STDOUT $RC_STDOUT.pipestatus
293 294
}

295
# run epm, possible from side repo
296 297
epm()
{
298
    if [ "$EPMMODE" = "pipe" ] ; then
299
        epm_main --inscript "$@"
300
        return
301
    fi
302 303 304

    # run epm again to full initialization
    local bashopt=''
305
    [ -n "$debug" ] && bashopt='-x'
306 307

    $CMDSHELL $bashopt $PROGDIR/$PROGNAME --inscript "$@"
308 309 310 311 312
}

# run $SUDO epm, possible from side repo
sudoepm()
{
313
    [ "$EPMMODE" = "pipe" ] && fatal "Can't use sudo epm call from the piped script"
314

315
    local bashopt=''
316
    [ -n "$debug" ] && bashopt='-x'
317

318
    sudorun $CMDSHELL $bashopt $PROGDIR/$PROGNAME --inscript "$@"
319
}
Vitaly Lipatov's avatar
Vitaly Lipatov committed
320 321 322 323

# Print error message and stop the program
fatal()
{
324 325
    local PROMOMESSAGE="$EPMPROMOMESSAGE"
    [ -n "$PROMOMESSAGE" ] || PROMOMESSAGE=" (you can discuss the epm $EPMVERSION problem in Telegram: https://t.me/useepm)"
326
    if [ -z "$TEXTDOMAIN" ] ; then
327 328 329
        set_color $RED >&2
        echo -n "ERROR: " >&2
        restore_color >&2
330
        echo "$* $PROMOMESSAGE" >&2
331 332 333 334 335
#    else
#        echog "Error in $0: $@" >&2
    fi
#    [ "$TERM" = "screen" ] && echo "(screen detected: waiting ten seconds to exit ...)" >&2 && sleep 10
    exit 1
Vitaly Lipatov's avatar
Vitaly Lipatov committed
336
}
337

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
# Print debug message
debug()
{
    [ -n "$debug" ] || return
    if [ -z "$TEXTDOMAIN" ] ; then
        set_color $YELLOW >&2
        echo -n "WARNING: " >&2
        restore_color >&2
        echo "$*" >&2
#    else
#        echog "Error in $0: $@" >&2
    fi
}


Vitaly Lipatov's avatar
Vitaly Lipatov committed
353 354 355
# Print warning message
warning()
{
356
    if [ -z "$TEXTDOMAIN" ] ; then
357 358 359 360
        set_color $YELLOW >&2
        echo -n "WARNING: " >&2
        restore_color >&2
        echo "$*" >&2
361 362 363
#    else
#        echog "Error in $0: $@" >&2
    fi
Vitaly Lipatov's avatar
Vitaly Lipatov committed
364 365
}

366 367
info()
{
368
    [ -n "$quiet" ] && return
369

370 371 372 373 374 375 376
    # print message to stderr if stderr forwarded to (a file)
    if isatty2 ; then
        isatty || return 0
        echo "$*"
    else
        echo "$*" >&2
    fi
377 378
}

379 380 381 382 383 384 385 386 387 388 389 390 391

check_su_root()
{
    [ "$BASEDISTRNAME" = "alt" ] || return 0

    is_root || return 0

    echo "$PATH" | grep -q "/usr/sbin" && return 0

    fatal "There is missed /usr/sbin path in PATH. Probably you have used 'su' without '-' to get root access. Use 'esu' or 'su -' command to get root permissions."
}


392 393 394
# if we have not sudo, returns 1 and set SUDO variable to fatal
SUDO_TESTED=''
SUDO_CMD='sudo'
395 396
set_sudo()
{
397 398 399 400 401 402 403 404 405 406 407 408 409 410
    local nofail="$1"

    # cache the result
    [ -n "$SUDO_TESTED" ] && return "$SUDO_TESTED"
    SUDO_TESTED="0"

    SUDO=""
    # skip SUDO if disabled
    [ -n "$EPMNOSUDO" ] && return
    if [ "$DISTRNAME" = "Cygwin" ] || [ "$DISTRNAME" = "Windows" ] ; then
        # skip sudo using on Windows
        return
    fi

411 412
    check_su_root

413 414 415 416 417 418 419
    # if we are root, do not need sudo
    is_root && return

    # start error section
    SUDO_TESTED="1"

    if ! is_command $SUDO_CMD ; then
420
        [ "$nofail" = "nofail" ] || SUDO="fatal 'For this operation run epm under root, or install and tune sudo (http://altlinux.org/sudo)'"
421
        SUDO_TESTED="2"
422 423 424 425 426
        return "$SUDO_TESTED"
    fi

    # if input is a console
    if inputisatty && isatty && isatty2 ; then
427 428 429
        if ! $SUDO_CMD -n true ; then
            info "Please enter sudo user password to use sudo in the current session."
            if ! $SUDO_CMD -l >/dev/null ; then
430
                [ "$nofail" = "nofail" ] || SUDO="fatal 'For this operation run epm under root, or install and tune sudo (http://altlinux.org/sudo)'"
431
                SUDO_TESTED="3"
432 433
                return "$SUDO_TESTED"
            fi
434 435 436
        fi
    else
        # use sudo if one is tuned and tuned without password
437 438
        # hack: check twice
        $SUDO_CMD -l -n >/dev/null 2>/dev/null
439
        if ! $SUDO_CMD -l -n >/dev/null 2>/dev/null ; then
440
            [ "$nofail" = "nofail" ] || SUDO="fatal 'Can't use sudo (only passwordless sudo is supported here). Please run epm under root or check http://altlinux.org/sudo '"
441
            SUDO_TESTED="4"
442 443 444 445 446 447 448 449 450 451
            return "$SUDO_TESTED"
        fi
    fi

    SUDO_TESTED="0"
    # FIXME: does not work: sudo -- VARIABLE=some command
    SUDO="$SUDO_CMD"
    #SUDO="$SUDO_CMD --"
    # check for < 1.7 version which do not support -- (and --help possible too)
    #$SUDO_CMD -h 2>/dev/null | grep -q "  --" || SUDO="$SUDO_CMD"
452

453 454
}

455 456 457
# return TRUE if we can run privileged command
sudo_allowed()
{
458
    set_sudo nofail
459 460
}

461 462
# wait for n seconds (if possible) during executing command
# args: seconds command
463 464
withtimeout()
{
465 466 467 468 469 470 471 472 473
    local TO=$(print_command_path timeout || print_command_path gtimeout)
    if [ -x "$TO" ] ; then
        $TO "$@"
        return
    fi
    fatal "Possible indefinite wait due timeout command is missed"
    # fallback: drop time arg and run without timeout
    #shift
    #"$@"
474 475
}

476 477
set_eatmydata()
{
478 479 480 481 482 483 484 485 486 487 488
    # don't use eatmydata (useless)
    return 0
    # skip if disabled
    [ -n "$EPMNOEATMYDATA" ] && return
    # use if possible
    is_command eatmydata || return
    set_sudo
    # FIXME: check if SUDO already has eatmydata
    [ -n "$SUDO" ] && SUDO="$SUDO eatmydata" || SUDO="eatmydata"
    [ -n "$verbose" ] && info "Uwaga! eatmydata is installed, we will use it for disable all sync operations."
    return 0
489 490
}

491 492
# 
__get_package_for_command()
493
{
494 495 496 497 498 499 500 501
    case "$1" in
        equery|revdep-rebuild)
            echo 'gentoolkit'
            ;;
        update-kernel|remove-old-kernels)
            echo 'update-kernel'
            ;;
    esac
502 503
}

504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
# TODO:
confirm() {
    local response
    # call with a prompt string or use a default
    read -r -p "${1:-Are you sure? [y/N]} " response
    case $response in
        [yY][eE][sS]|[yY])
            true
            ;;
        *)
            false
            ;;
    esac
}

519 520 521

confirm_info()
{
522 523 524 525
    info "$*"
    if [ -z "$non_interactive" ] ; then
        confirm "Are you sure? [y/N]" || fatal "Exiting"
    fi
526 527 528 529

}


530 531
is_root()
{
532 533
    local EFFUID="$(id -u)"
    [ "$EFFUID" = "0" ]
534 535
}

536 537
assure_root()
{
538
    is_root || fatal "run me only under root"
539 540
}

541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
check_su_access()
{
    is_command su && return
    [ ! -f /bin/su ] && warning "/bin/su is missed. Try install su package (http://altlinux.org/su)." && return 1
    local group="$(stat -c '%G' /bin/su)" || fatal
    warning "Check if you are in $group group to have access to su command."
    return 1
}

check_sudo_access()
{
    is_command sudo && return
    local cmd=''
    local i
    for i in /bin/sudo /usr/bin/sudo ; do
        [ -f $i ] && cmd="$i"
    done
558 559
    [ ! -f "$cmd" ] && warning "sudo command is missed. Try install sudo package (http://altlinux.org/sudo)." && return 1
    local group="$(stat -c '%G' "$cmd")" || fatal
560 561 562 563 564 565 566 567 568 569 570 571
    warning "Check if you are in $group group to have access to sudo command."
    return 1
}

check_sudo_access_only()
{
    is_command sudo && return
    local cmd=''
    local i
    for i in /bin/sudo /usr/bin/sudo ; do
        [ -f $i ] && cmd="$i"
    done
572 573
    [ ! -f "$cmd" ] && return 1
    local group="$(stat -c '%G' "$cmd")" || fatal
574 575 576 577
    warning "sudo command is presence, but is not accessible for you. Check if you are in $group group to have access to sudo command."
    return 1
}

578 579 580 581 582 583 584 585 586
esu()
{
    if is_root ; then
        if [ -n "$*" ] ; then
            [ -n "$quiet" ] || showcmd "$*"
            exec "$@"
        else
            # just shell
            showcmd "su -"
587
            a= exec su -
588 589 590 591 592 593
        fi
    fi

    set_pm_type


Vitaly Lipatov's avatar
Vitaly Lipatov committed
594 595 596 597 598 599 600
# TODO:
#quote() {
#    for arg in "$@"; do
#        printf '%s\n' "$arg" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
#    done
#}

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
    escape_args()
    {
        local output=''
        while [ -n "$1" ] ; do
            if has_space "$1" ; then
                [ -n "$output" ] && output="$output '$1'" || output="'$1'"
            else
                [ -n "$output" ] && output="$output $1" || output="$1"
            fi
            shift
        done
        echo "$output"
    }

    escaped="$(escape_args "$@")"

617
    check_sudo_access_only
618 619
    # sudo is not accessible, will ask root password
    if ! set_sudo ; then
620
        check_su_access
621 622 623
        #info "Enter root password:"
        if [ -n "$*" ] ; then
            [ -n "$quiet" ] || showcmd "su - -c $escaped"
624
            a= exec su - -c "$escaped"
625 626 627
        else
            # just shell
            showcmd "su -"
628
            a= exec su -
629 630 631
        fi
    fi

632 633
    check_sudo_access

634 635 636 637 638 639 640 641 642 643
    #info "You can be asked about your password:"
    if [ -n "$*" ] ; then
        [ -n "$quiet" ] || showcmd "$SUDO su - -c $escaped"
        $SUDO su - -c "$escaped"
    else
        showcmd "$SUDO su -"
        $SUDO su -
    fi
}

644 645
regexp_subst()
{
646 647 648
    local expression="$1"
    shift
    sed -i -r -e "$expression" "$@"
649 650
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
651
# TODO: we we can't use epm directly?
652 653
assure_exists()
{
654 655 656
    load_helper epm-assure
    local package="$2"
    [ -n "$package" ] || package="$(__get_package_for_command "$1")"
657 658 659 660 661

    # ask for install: https://bugzilla.altlinux.org/42240
    local ask=''
    [ -n "$non_interactive" ] || ask=1

662
    ( verbose='' direct='' interactive=$ask epm_assure "$1" $package $3 ) || fatal
663 664
}

665 666
assure_exists_erc()
{
667 668 669
    load_helper epm-assure
    local package="erc"
    ( direct='' epm_assure "$package" ) || epm ei erc || fatal "erc is not available to install."
670 671
}

672
# will replaced within disabled_eget in packaged version
Vitaly Lipatov's avatar
Vitaly Lipatov committed
673
eget()
674
{
675 676
    # use internal eget only if exists
    if [ -s $SHAREDIR/tools_eget ] ; then
677
        ( EGET_BACKEND=$eget_backend $CMDSHELL $SHAREDIR/tools_eget "$@" )
678 679 680
        return
    fi
    fatal "Internal error: missed tools_eget"
681

Vitaly Lipatov's avatar
Vitaly Lipatov committed
682
    local EGET
683 684 685 686 687
    # FIXME: we need disable output here, eget can be used for get output
    assure_exists eget eget 3.3 >/dev/null
    # run external command, not the function
    EGET=$(print_command_path eget) || fatal "Missed command eget from installed package eget"
    $EGET "$@"
688 689
}

690

691 692
__epm_assure_7zip()
{
693 694 695 696
    # install 7zip in any case (can be used)
    if is_command 7z || is_command 7za || is_command 7zr || is_command 7zz ; then
        :
    else
697
        epm install 7-zip || epm install p7zip
698
    fi
699 700 701 702 703 704
}

# will replaced within disabled_erc in packaged version
erc()
{

Vitaly Lipatov's avatar
Vitaly Lipatov committed
705
    __epm_assure_7zip
706

707 708
    # use internal eget only if exists
    if [ -s $SHAREDIR/tools_erc ] ; then
709
        $CMDSHELL $SHAREDIR/tools_erc "$@"
710 711 712
        return
    fi
    fatal "Internal error: missed tools_erc"
713

714 715 716
    # FIXME: we need disable output here, ercat can be used for get output
    assure_exists_erc >/dev/null
    # run external command, not the function
717
    local ERC
718 719
    ERC=$(print_command_path erc) || fatal "Missed command erc from installed package erc"
    $ERC "$@"
720 721 722 723 724
}

# will replaced within disabled_ercat in packaged version
ercat()
{
725 726 727
    local ERCAT
    # use internal eget only if exists
    if [ -s $SHAREDIR/tools_ercat ] ; then
728
        $CMDSHELL $SHAREDIR/tools_ercat "$@"
729 730 731
        return
    fi
    fatal "Internal error: missed tools_ercat"
732

733 734 735 736 737
    # FIXME: we need disable output here, ercat can be used for get output
    assure_exists_erc >/dev/null
    # run external command, not the function
    ERCAT=$(print_command_path ercat) || fatal "Missed command ercat from installed package erc"
    $ERCAT "$@"
738 739
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
740 741
estrlist()
{
742
    if [ -s $SHAREDIR/tools_estrlist ] ; then
743
        $CMDSHELL $SHAREDIR/tools_estrlist "$@"
744 745 746
        return
    fi
    fatal "missed tools_estrlist"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
747 748 749 750
}

onefile_estrlist()
{
751
    internal_tools_estrlist "$@"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
752 753
}

754 755
# will replaced within eget() in packed version
onefile_eget()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
756
{
757 758 759 760 761
    # check for both
    # we really need that cross here,
    is_command curl || assure_exists wget
    is_command wget || assure_exists curl
    internal_tools_eget "$@"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
762 763
}

764
# TODO: improve and drop!
765 766
get_package_type()
{
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
    local i
    case $1 in
        *.deb)
            echo "deb"
            return
            ;;
        *.rpm)
            echo "rpm"
            return
            ;;
        *.txz)
            echo "txz"
            return
            ;;
        *.tbz)
            echo "tbz"
            return
            ;;
        *.exe)
            echo "exe"
            return
            ;;
        *.msi)
            echo "msi"
            return
            ;;
        *.AppImage)
            echo "AppImage"
            return
            ;;
        *)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
798
            if [ -r "$1" ] && file "$1" | grep -q " ELF " ; then
799 800 801
                echo "ELF"
                return
            fi
802
            # print extension by default
803
            basename "$1" | sed -e 's|.*\.||'
804 805 806
            return 1
            ;;
    esac
807 808 809
}


810
# print options description from HELPCMD/HELPOPT lines in the code
811
# args: section_name, [file with code]
812 813
get_help()
{
814 815 816
    if [ "$0" = "/dev/stdin" ] || [ "$0" = "sh" ] ; then
        return
    fi
817
    local F="$0"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
818 819 820
    if [ -n "$2" ] ; then
        is_dirpath "$2" && F="$2" || F="$(dirname $0)/$2"
    fi
821

822
    cat "$F" | grep -- "# $1" | while read -r n ; do
Vitaly Lipatov's avatar
Vitaly Lipatov committed
823 824 825 826 827 828
        if echo "$n" | grep -q "# $1: PART: " ; then
            echo
            echo "$n" | sed -e "s|# $1: PART: ||"
            continue
        fi
        echo "$n" | grep -q "^ *#" && continue
829 830 831
        opt=`echo $n | sed -e "s|) # $1:.*||g" -e 's|"||g' -e 's@^|@@'`
        desc=`echo $n | sed -e "s|.*) # $1:||g"`
        printf "    %-20s %s\n" "$opt" "$desc"
832 833 834
    done
}

835
set_bigtmpdir()
836
{
837 838 839 840
    # TODO: improve BIGTMPDIR conception
    # https://bugzilla.mozilla.org/show_bug.cgi?id=69938
    # https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s15.html
    # https://geekpeach.net/ru/%D0%BA%D0%B0%D0%BA-systemd-tmpfiles-%D0%BE%D1%87%D0%B8%D1%89%D0%B0%D0%B5%D1%82-tmp-%D0%B8%D0%BB%D0%B8-var-tmp-%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0-tmpwatch-%D0%B2-centos-rhel-7
841 842 843 844
    if [ -z "$BIGTMPDIR" ] ; then
        BIGTMPDIR="/var/tmp"
        [ -d "$BIGTMPDIR" ] || BIGTMPDIR="$TMPDIR"
    fi
845 846 847 848 849 850 851
    export BIGTMPDIR
}

assure_tmpdir()
{
    if [ -z "$TMPDIR" ] ; then
        export TMPDIR="/tmp"
852
        debug "Your have no TMPDIR defined. Using $TMPDIR as fallback."
853 854
    fi

855 856 857 858
    if [ ! -d "$TMPDIR" ] ; then
        fatal "TMPDIR $TMPDIR does not exist."
    fi

859 860 861 862 863
    if [ ! -w "$TMPDIR" ] ; then
        fatal "TMPDIR $TMPDIR is not writable."
    fi
}

864 865 866 867 868 869 870 871
test_shell()
{
    local R
    R="$($CMDSHELL /dev/null 2>&1)"
    [ -n "$R" ] && fatal "$CMDSHELL is broken (bash wrongly printing out '$R'). Check ~/.bashrc and /etc/bashrc, run $CMDSHELL manually for test."
}


872 873
set_distro_info()
{
874 875 876

    test_shell

877 878 879 880 881 882 883 884 885 886 887 888
    assure_tmpdir

    set_bigtmpdir

    # don't run again in subprocesses
    [ -n "$DISTRVENDOR" ] && return 0

    DISTRVENDOR=$PROGDIR/distr_info

    # export pack of variables, see epm print info --print-eepm-env
    [ -n "$verbose" ] && $DISTRVENDOR --print-eepm-env
    eval $($DISTRVENDOR --print-eepm-env | grep -v '^ *#')
889 890 891 892 893
}

# FIXME: detect if not recognized
set_pm_type()
{
894 895
    local CMD
    set_distro_info
896

897
# override package manager detection result
898 899 900 901 902
if [ -n "$EPM_BACKEND" ] ; then
    PMTYPE=$EPM_BACKEND
    return
fi
# obsoleted
903
if [ -n "$FORCEPM" ] ; then
904 905
    PMTYPE=$FORCEPM
    return
906 907
fi

908
}
909

910 911
is_active_systemd()
{
912
    [ "$DISTRCONTROL" = "systemd" ]
913
}
914 915 916

assure_distr()
{
917 918 919
    local TEXT="this option"
    [ -n "$2" ] && TEXT="$2"
    [ "$DISTRNAME" = "$1" ] || fatal "$TEXT supported only for $1 distro"
920
}
921 922 923 924 925

# return delimiter sign in depend of package type
get_pkg_name_delimiter()
{
   local pkgtype="$1"
926
   [ -n "$pkgtype" ] || pkgtype="$PKGFORMAT"
927 928 929 930

   [ "$pkgtype" = "deb" ] && echo "_" && return
   echo "-"
}
931

932
# used via remove_on_exit
933 934
__epm_remove_tmp_files()
{
935
    trap "-" EXIT
936 937
    [ -n "$DEBUG" ] && return 0

938 939
    [ -n "$verbose" ] && info "Removing tmp files on exit ..."

940 941
    if [ -n "$to_clean_tmp_dirs" ] ; then
        echo "$to_clean_tmp_dirs" | while read p ; do
942 943
            [ -n "$verbose" ] && echo "rm -rf '$p'"
            rm -rf "$p" 2>/dev/null
944 945 946 947 948
        done
    fi

    if [ -n "$to_clean_tmp_files" ] ; then
        echo "$to_clean_tmp_files" | while read p ; do
949
            rm $verbose -f "$p" 2>/dev/null
950
        done
951
    fi
952

953 954 955 956
    return 0
}


957 958
remove_on_exit()
{
959 960 961 962
    if [ -z "$set_remove_on_exit" ] ; then
        trap "__epm_remove_tmp_files" EXIT
        set_remove_on_exit=1
    fi
963 964
    while [ -n "$1" ] ; do
        if [ -d "$1" ] ; then
965 966
            to_clean_tmp_dirs="$to_clean_tmp_dirs
$1"
967
        elif [ -f "$1" ] ; then
968 969
            to_clean_tmp_files="$to_clean_tmp_files
$1"
970 971 972 973 974
        fi
        shift
    done
}

975 976 977 978 979
#has_space()
#{
#    estrlist -- has_space "$@"
#}
# use internal implementation for speed
980 981
has_space()
{
982 983 984
        # not for dash:
        [ "$1" != "${1/ //}" ]
        # [ "$(echo "$*" | sed -e "s| ||")" != "$*" ]
985
}
986

987

988 989
is_url()
{
990
    echo "$1" | grep -q "^[filehtps]*:/"
991 992
}

993
# print a path to the command if exists in $PATH
994
if a= type -a type 2>/dev/null >/dev/null ; then
995 996
print_command_path()
{
997
    a= type -fpP -- "$1" 2>/dev/null
998
}
999 1000 1001
elif a= which which 2>/dev/null >/dev/null ; then
    # the best case if we have which command (other ways needs checking)
    # TODO: don't use which at all, it is a binary, not builtin shell command
1002 1003
print_command_path()
{
1004
    a= which -- "$1" 2>/dev/null
1005 1006 1007 1008
}
else
print_command_path()
{
1009
    a= type "$1" 2>/dev/null | sed -e 's|.* /|/|'
1010 1011 1012 1013 1014 1015 1016 1017 1018
}
fi

# check if <arg> is a real command
is_command()
{
    print_command_path "$1" >/dev/null
}

1019
# compatibility layer
1020

1021
# add realpath if missed (with -s support)
1022
if ! is_command realpath ; then
1023 1024 1025
realpath()
{
    [ -n "$*" ] || return
1026 1027 1028 1029 1030
    if [ "$1" = "-s" ] ; then
        shift
        echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")" #"
        return
    fi
1031 1032 1033 1034
    readlink -f "$@"
}
fi

1035

1036 1037 1038 1039 1040
# TODO: use perl if sed -i is not accessible
# sed -i is only supported in GNU sed.
#  sed -i "s/$find/$replace/g" "$@"
#  perl -p -i -e "s/$find/$replace/g" "$@"

1041
# add subst if missed
1042
if ! is_command subst ; then
1043 1044 1045 1046 1047
subst()
{
    sed -i -e "$@"
}
fi
1048 1049 1050

check_core_commands()
{
1051 1052 1053
    #which which >/dev/null || fatal "Can't find which command (which or debianutils package is missed?)"
    is_command grep || fatal "Can't find grep command (coreutils package is missed?)"
    is_command sed || fatal "Can't find sed command (sed package is missed?)"
1054 1055
}