distr_info 32.2 KB
Newer Older
1
#!/bin/sh
2 3 4
# 2007-2023 (c) Vitaly Lipatov <lav@etersoft.ru>
# 2007-2023 (c) Etersoft
# 2007-2023 Public domain
5 6 7 8

# You can set ROOTDIR to root system dir
#ROOTDIR=

9
PROGVERSION="20250206"
10

11 12
# TODO: check /etc/system-release

13 14 15
# Check for DISTRO specific file in /etc
distro()
{
16 17 18 19
    #[ -n "$ROOTDIR" ] || return
    # fill global DISTROFILE
    DISTROFILE="$ROOTDIR/etc/$1"
    [ -f "$DISTROFILE" ]
20 21 22 23 24
}

# Has a distro file the specified word?
has()
{
25 26
    [ -n "$DISTROFILE" ] || exit 1
    grep "$*" "$DISTROFILE" >/dev/null 2>&1
27 28
}

29 30
# copied from epm-sh-functions
# print a path to the command if exists in $PATH
31
if a='' which which 2>/dev/null >/dev/null ; then
32 33 34
    # the best case if we have which command (other ways needs checking)
    # TODO: don't use which at all, it is binary, not builtin shell command
print_command_path()
35
{
36
    a='' which -- "$1" 2>/dev/null
37
}
38
elif a='' type -a type 2>/dev/null >/dev/null ; then
39 40
print_command_path()
{
41
    a='' type -fpP -- "$1" 2>/dev/null
42 43 44 45
}
else
print_command_path()
{
46
    a='' type "$1" 2>/dev/null | sed -e 's|.* /|/|'
47 48 49 50 51 52 53 54 55 56
}
fi

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

57

58 59
firstupper()
{
60 61
    # FIXME: works with GNU sed only
    echo "$*" | sed 's/.*/\u&/'
62 63
}

64 65
tolower()
{
66 67 68
    # tr is broken in busybox (checked with OpenWrt)
    #echo "$*" | tr "[:upper:]" "[:lower:]"
    echo "$*" | awk '{print tolower($0)}'
69 70
}

71 72 73 74 75 76 77 78 79 80 81 82 83
# copied from estrlist
firstword()
{
        echo "$*" | cut -f1 -d" "
}

lastword()
{
        echo "$*" | xargs -n1 echo 2>/dev/null | tail -n1
}



84 85
print_bug_report_url()
{
86
    echo "$BUG_REPORT_URL"
87 88
}

89
# allows x86_64/Distro/Version
90 91
override_distrib()
{
92 93
    [ -n "$DISTRNAMEOVERRIDE" ] || DISTRNAMEOVERRIDE="$1"
    [ -n "$DISTRNAMEOVERRIDE" ] || return
94

95 96 97 98 99
    local name="$(echo "$DISTRNAMEOVERRIDE" | sed -e 's|x86_64/||')"
    [ "$name" = "$DISTRNAMEOVERRIDE" ] && DIST_ARCH="x86" || DIST_ARCH="x86_64"
    DISTRIB_ID="$(echo "$name" | sed -e 's|/.*||')"
    DISTRIB_RELEASE="$(echo "$name" | sed -e 's|.*/||')"
    [ "$DISTRIB_ID" = "$DISTRIB_RELEASE" ] && DISTRIB_RELEASE=''
100

101
    VENDOR_ID=''
102
    PRETTY_NAME="$DISTRIB_ID"
103 104 105
    DISTRO_NAME="$DISTRIB_ID"
    DISTRIB_CODENAME="$DISTRIB_RELEASE"
    DISTRIB_FULL_RELEASE="$DISTRIB_RELEASE"
106

107 108
}

109 110
# Translate DISTRIB_ID to vendor name (like %_vendor does or package release name uses), uses VENDOR_ID by default
pkgvendor()
111
{
112 113 114 115 116 117 118 119 120
    [ "$DISTRIB_ID" = "ALTLinux" ] && echo "alt" && return
    [ "$DISTRIB_ID" = "ALTServer" ] && echo "alt" && return
    [ "$DISTRIB_ID" = "MOC" ] && echo "alt" && return
    [ "$DISTRIB_ID" = "MESh" ] && echo "alt" && return
    [ "$DISTRIB_ID" = "AstraLinuxSE" ] && echo "astra" && return
    [ "$DISTRIB_ID" = "AstraLinuxCE" ] && echo "astra" && return
    [ "$DISTRIB_ID" = "LinuxXP" ] && echo "lxp" && return
    [ "$DISTRIB_ID" = "TinyCoreLinux" ] && echo "tcl" && return
    [ "$DISTRIB_ID" = "VoidLinux" ] && echo "void" && return
121
    [ "$DISTRIB_ID" = "ManjaroLinux" ] && echo "manjaro" && return
122 123 124 125 126 127 128 129
    [ "$DISTRIB_ID" = "OpenSUSE" ] && echo "suse" && return
    [ "$DISTRIB_ID" = "openSUSETumbleweed" ] && echo "suse" && return
    [ "$DISTRIB_ID" = "openSUSELeap" ] && echo "suse" && return
    if [ -n "$VENDOR_ID" ] ; then
        echo "$VENDOR_ID"
        return
    fi
    tolower "$DISTRIB_ID"
130 131
}

132 133 134
# TODO: in more appropriate way
#which pkcon 2>/dev/null >/dev/null && info "You can run $ PMTYPE=packagekit epm to use packagekit backend"

135
# Print package manager (need DISTRIB_ID, DISTRIB_RELEASE vars)
136
# used in package manager detection via distro name
137 138 139
pkgmanager()
{
local CMD
140 141 142 143

case $VENDOR_ID in
    alt)
        echo "apt-rpm" && return
144
        ;;
145 146 147 148 149
    arch|manjaro)
        echo "pacman" && return
        ;;
    debian)
        echo "apt-dpkg" && return
150
        ;;
151 152 153 154
esac

# FIXME: some problems with multibased distros (Server Edition on CentOS and Desktop Edition on Ubuntu)
case $DISTRIB_ID in
155 156 157
    PCLinux)
        CMD="apt-rpm"
        ;;
158
    Ubuntu|Debian|Mint|OSnovaLinux|Uncom|AstraLinux*|Elbrus)
159 160 161 162 163 164 165
        CMD="apt-dpkg"
        #which aptitude 2>/dev/null >/dev/null && CMD=aptitude-dpkg
        #is_command snappy && CMD=snappy
        ;;
    Solus)
        CMD="eopkg"
        ;;
166 167 168
    PisiLinux)
        CMD="pisi"
        ;;
169 170 171
    Mandriva)
        CMD="urpm-rpm"
        ;;
172
    ROSA|NAME="OpenMandrivaLx")
173 174 175 176 177 178 179 180 181 182 183 184 185
        CMD="urpm-rpm"
        is_command yum && CMD="yum-rpm"
        is_command dnf && CMD="dnf-rpm"
        # use dnf since 2020
        #[ "$DISTRIB_ID/$DISTRIB_RELEASE" = "ROSA/2020" ] && CMD="urpm-rpm"
        ;;
    FreeBSD|NetBSD|OpenBSD|Solaris)
        CMD="pkgsrc"
        is_command pkg && CMD=pkgng
        ;;
    Gentoo)
        CMD="emerge"
        ;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
186 187 188
    Redox)
        CMD="redox-pkg"
        ;;
189
    ArchLinux|ManjaroLinux)
190 191
        CMD="pacman"
        ;;
192
    Fedora|CentOS|OracleLinux|RockyLinux|AlmaLinux|RHEL|RELS|Scientific|GosLinux|Amzn|RedOS|MSVSphere)
193 194 195 196 197 198 199 200 201 202 203 204 205 206
        CMD="dnf-rpm"
        is_command dnf || CMD="yum-rpm"
        [ "$DISTRIB_ID/$DISTRIB_RELEASE" = "CentOS/7" ] && CMD="yum-rpm"
        ;;
    Slackware)
        CMD="slackpkg"
        ;;
    SUSE|SLED|SLES|openSUSETumbleweed|openSUSELeap)
        CMD="zypper-rpm"
        ;;
    ForesightLinux|rPathLinux)
        CMD="conary"
        ;;
    Windows)
207 208
        is_command winget && echo "winget" && return
        is_command appget && CMD="appget"
209
        is_command choco && CMD="choco"
210
        is_command npackdcl && CMD="npackd"
211 212 213 214 215 216 217 218 219 220
        ;;
    MacOS)
        CMD="homebrew"
        ;;
    OpenWrt)
        CMD="opkg"
        ;;
    GNU/Linux/Guix)
        CMD="guix"
        ;;
221 222 223
    NixOS)
        CMD="nix"
        ;;
224 225
    Android)
        CMD="android"
226
        # TODO: CMD="termux-pkg"
227 228 229 230
        ;;
    Cygwin)
        CMD="aptcyg"
        ;;
231
    AlpineLinux)
232 233 234 235 236 237 238 239 240 241
        CMD="apk"
        ;;
    TinyCoreLinux)
        CMD="tce"
        ;;
    VoidLinux)
        CMD="xbps"
        ;;
    *)
        if is_command "rpm" && [ -s /var/lib/rpm/Name ] || [ -s /var/lib/rpm/rpmdb.sqlite ] ; then
242
            is_command "apt-get" && [ -d /var/lib/apt ] && echo "apt-rpm" && return
243 244 245 246 247 248 249 250 251 252 253
            is_command "zypper" && echo "zypper-rpm" && return
            is_command "dnf" && echo "dnf-rpm" && return
            is_command "yum" && echo "yum-rpm" && return
            is_command "urpmi" && echo "urpm-rpm" && return
        fi

        if is_command "dpkg" && [ -s /var/lib/dpkg/status ] ; then
            is_command "apt" && echo "apt-dpkg" && return
            is_command "apt-get" && echo "apt-dpkg" && return
        fi

254
        echo "pkgmanager(): We don't support yet DISTRIB_ID $DISTRIB_ID (VENDOR_ID $VENDOR_ID)" >&2
255
        ;;
256
esac
257
if [ "$CMD" = "dnf-rpm" ] && a= dnf --version | grep -qi "dnf5" ; then
258 259
    CMD="dnf5-rpm"
fi
260 261 262
echo "$CMD"
}

263 264 265
# Print pkgtype (need DISTRIB_ID var)
pkgtype()
{
266 267 268 269 270 271 272

    case $VENDOR_ID in
        arch|manjaro)
            echo "pkg.tar.xz" && return
            ;;
    esac

273 274
# TODO: try use generic names
    case $(pkgvendor) in
275 276 277 278 279 280 281 282 283 284 285 286 287
        freebsd) echo "tbz" ;;
        sunos) echo "pkg.gz" ;;
        slackware|mopslinux) echo "tgz" ;;
        archlinux|manjaro) echo "pkg.tar.xz" ;;
        gentoo) echo "tbz2" ;;
        windows) echo "exe" ;;
        android) echo "apk" ;;
        alpine) echo "apk" ;;
        tinycorelinux) echo "tcz" ;;
        voidlinux) echo "xbps" ;;
        openwrt) echo "ipk" ;;
        cygwin) echo "tar.xz" ;;
        solus) echo "eopkg" ;;
288
        pisilinux) echo "pisi" ;;
289 290 291 292 293 294 295
        *)
            case $(pkgmanager) in
                *-dpkg)
                    echo "deb" ;;
                *-rpm)
                    echo "rpm" ;;
                *)
296
                    echo "" ;;
297 298
            esac
    esac
299 300
}

301 302
print_codename()
{
303
    echo "$DISTRIB_CODENAME"
304
}
305

306 307
print_repo_name()
{
308
    echo "$DISTRIB_CODENAME"
309 310
}

311 312
get_var()
{
313 314
    # get first variable and print it out, drop quotes if exists
    grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/"
315 316 317 318 319
}

# 2010.1 -> 2010
get_major_version()
{
320
    echo "$1" | sed -e "s/\..*//g"
321 322
}

323 324
normalize_name()
{
325 326 327 328 329 330 331
    case "$1" in
        "RED OS")
            echo "RedOS"
            ;;
        "Debian GNU/Linux")
            echo "Debian"
            ;;
332 333 334
        "Liya GNU/Linux")
            echo "LiyaLinux"
            ;;
335 336 337 338 339 340
        "CentOS Linux")
            echo "CentOS"
            ;;
        "Fedora Linux")
            echo "Fedora"
            ;;
341 342 343
        "Pardus GNU/Linux")
            echo "Pardus"
            ;;
344 345 346 347 348 349 350 351 352
        "Red Hat Enterprise Linux Server")
            echo "RHEL"
            ;;
        "ROSA Fresh"*|"ROSA Desktop Fresh"*)
            echo "ROSA"
            ;;
        "ROSA Chrome Desktop")
            echo "ROSA"
            ;;
353
        "MOS Desktop"|"MOS Panel")
354 355
            echo "ROSA"
            ;;
356 357 358 359 360 361
        "ROSA Enterprise Linux Desktop")
            echo "RELS"
            ;;
        "ROSA Enterprise Linux Server")
            echo "RELS"
            ;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
362 363 364
        "uos")
            echo "UOS"
            ;;
365 366 367 368 369 370
        *)
            #echo "${1// /}"
            #firstupper "$1" | sed -e "s/ //g" -e 's|(.*||'
            echo "$1" | sed -e "s/ //g" -e 's|(.*||'
            ;;
    esac
371 372
}

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
# 1.2.3.4.5 -> 1
normalize_version1()
{
    echo "$1" | sed -e "s|\..*||"
}

# 1.2.3.4.5 -> 1.2
normalize_version2()
{
    echo "$1" | sed -e "s|^\([^.][^.]*\.[^.][^.]*\)\..*|\1|"
}

# 1.2.3.4.5 -> 1.2.3
normalize_version3()
{
    echo "$1" | sed -e "s|^\([^.][^.]*\.[^.][^.]*\.[^.][^.]*\)\..*|\1|"
}

391 392 393 394 395
is_numeric()
{
    echo "$1" | grep -q "^[0-9][0-9]*$"
}

396

397 398
fill_distr_info()
{
399
# Default values
400
PRETTY_NAME=""
401
DISTRIB_ID=""
402
DISTRIB_RELEASE=""
403 404
DISTRIB_FULL_RELEASE=""
DISTRIB_RELEASE_ORIG=""
405
DISTRIB_CODENAME=""
406
BUG_REPORT_URL=""
407
BUILD_ID=""
408

409
# Default detection by /etc/os-release
410 411
# https://www.freedesktop.org/software/systemd/man/os-release.html
if distro os-release ; then
412 413 414 415 416 417 418
    # shellcheck disable=SC1090
    . $DISTROFILE
    DISTRO_NAME="$NAME"
    DISTRIB_ID="$(normalize_name "$NAME")"
    DISTRIB_RELEASE_ORIG="$VERSION_ID"
    DISTRIB_RELEASE="$VERSION_ID"
    [ -n "$DISTRIB_RELEASE" ] || DISTRIB_RELEASE="CUR"
419
    [ "$BUILD_ID" = "rolling" ] && DISTRIB_RELEASE="rolling"
420
    [ -n "$BUG_REPORT_URL" ] || BUG_REPORT_URL="$HOME_URL"
421 422 423
    # set by os-release:
    #PRETTY_NAME
    VENDOR_ID="$ID"
424
    DISTRIB_CODENAME="$VERSION_CODENAME"
425
    case "$VENDOR_ID" in
426
        ubuntu|reld|rhel|astra|manjaro|redos|msvsphere|alteros|rockylinux|almalinux)
427 428
            ;;
        *)
429 430
            if [ -n "$ID_LIKE" ] ; then
                # ID_LIKE can be 'rhel centos fedora', use first word
431
                VENDOR_ID="$(firstword "$ID_LIKE")"
432 433
                # use latest word for versions like Fedora has
                if is_numeric "$DISTRIB_RELEASE" && [ "$DISTRIB_RELEASE" -ge 20 ] ; then
434
                    VENDOR_ID="$(lastword "$ID_LIKE")"
435
                fi
436 437 438
                if [ "$VENDOR_ID" = "debian" ] && [ -n "$DEBIAN_CODENAME" ] ; then
                    DISTRIB_CODENAME="$DEBIAN_CODENAME"
                fi
439
            fi
440 441
            ;;
    esac
442 443 444 445 446
    case "$VENDOR_ID" in
        reld|rhel|msvsphere|alteros|rockylinux|almalinux)
            DISTRIB_RELEASE=$(normalize_version1 "$DISTRIB_RELEASE")
            ;;
    esac
447
    DISTRIB_FULL_RELEASE="$DISTRIB_RELEASE"
448

449
elif distro lsb-release ; then
450 451 452 453 454 455 456
    DISTRIB_ID=$(cat $DISTROFILE | get_var DISTRIB_ID)
    DISTRO_NAME=$(cat $DISTROFILE | get_var DISTRIB_ID)
    DISTRIB_RELEASE="$(cat $DISTROFILE | get_var DISTRIB_RELEASE)"
    DISTRIB_RELEASE_ORIG="$DISTRIB_RELEASE"
    DISTRIB_FULL_RELEASE="$DISTRIB_RELEASE"
    DISTRIB_CODENAME=$(cat $DISTROFILE | get_var DISTRIB_CODENAME)
    PRETTY_NAME=$(cat $DISTROFILE | get_var DISTRIB_DESCRIPTION)
457 458
fi

459
DISTRIB_RELEASE=$(normalize_version2 "$DISTRIB_RELEASE")
460
[ -n "$DISTRIB_CODENAME" ] || DISTRIB_CODENAME=$DISTRIB_RELEASE
461 462

case "$VENDOR_ID" in
463 464 465 466 467 468
    "altlinux")
        VENDOR_ID="alt"
esac

case "$VENDOR_ID" in
    "alt")
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
        # 2.4.5.99 -> 2
        DISTRIB_RELEASE=$(normalize_version1 "$DISTRIB_RELEASE_ORIG")
        case "$DISTRIB_ID" in
            "ALTServer"|"ALTSPWorkstation"|"Sisyphus")
                ;;
            *)
                DISTRIB_ID="ALTLinux"
                ;;
        esac
        ;;
    "astra")
        DISTRIB_RELEASE=$(normalize_version2 "$DISTRIB_RELEASE_ORIG" | sed -e 's|_.*||')
        DISTRIB_FULL_RELEASE=$(normalize_version3 "$DISTRIB_RELEASE_ORIG" | sed -e 's|_.*||')
        if [ "$VARIANT" = "orel" ] || [ "$VARIANT" = "Orel" ] ; then
            DISTRIB_ID="AstraLinuxCE"
        else
            DISTRIB_ID="AstraLinuxSE"
        fi
        if [ "$DISTRIB_ID" = "AstraLinuxSE" ] ; then
            local fr="$(cat /etc/astra_version 2>/dev/null)"
            [ -n "$fr" ] && echo "$fr" | grep -q "$DISTRIB_RELEASE" && DISTRIB_FULL_RELEASE="$fr"
        fi
        ;;
492
    "fedora")
493
        DISTRIB_ID="Fedora"
494
        ;;
495 496 497
esac

case "$DISTRIB_ID" in
498 499 500 501
    "ALTLinux")
        echo "$VERSION" | grep -q "c9.* branch" && DISTRIB_RELEASE="c9"
        echo "$VERSION" | grep -q "c9f1 branch" && DISTRIB_RELEASE="c9f1"
        echo "$VERSION" | grep -q "c9f2 branch" && DISTRIB_RELEASE="c9f2"
502
        echo "$VERSION" | grep -q "c9f3 branch" && DISTRIB_RELEASE="c9f3"
503 504
        DISTRIB_CODENAME="$DISTRIB_RELEASE"
        # FIXME: fast hack for fallback: 10.1 -> p10 for /etc/os-release
505 506 507 508
        if echo "$DISTRIB_RELEASE" | grep -q "^0" ; then
            DISTRIB_RELEASE="Sisyphus"
            DISTRIB_CODENAME="$DISTRIB_RELEASE"
        elif echo "$DISTRIB_RELEASE" | grep -q "^[0-9]" && echo "$DISTRIB_RELEASE" | grep -q -v "[0-9][0-9][0-9]"  ; then
509 510 511
            DISTRIB_CODENAME="$(echo p$DISTRIB_RELEASE | sed -e 's|\..*||')"
            # TODO: change p10 to 10
            DISTRIB_RELEASE="$DISTRIB_CODENAME"
512 513 514
        fi
        ;;
    "ALTServer")
515
        DISTRIB_ID="ALTLinux"
516
        DISTRIB_CODENAME="$(echo p$DISTRIB_RELEASE | sed -e 's|\..*||')"
517 518
        # TODO: change p10 to 10
        DISTRIB_RELEASE="$DISTRIB_CODENAME"
519 520 521 522 523
        ;;
    "ALTSPWorkstation")
        DISTRIB_ID="ALTLinux"
        case "$DISTRIB_RELEASE_ORIG" in
            8.0|8.1)
524
                DISTRIB_RELEASE="c8"
525 526 527 528 529 530 531 532 533 534 535
                ;;
            8.2|8.3)
                DISTRIB_RELEASE="c9f1"
            ;;
            8.4)
                DISTRIB_RELEASE="c9f2"
            ;;
            8.*)
                DISTRIB_RELEASE="c9f3"
            ;;
        esac
536
        [ -n "$ALT_BRANCH_ID" ] && DISTRIB_RELEASE="$ALT_BRANCH_ID"
537 538 539 540 541 542 543 544
        DISTRIB_CODENAME="$DISTRIB_RELEASE"
#        DISTRIB_RELEASE=$(echo $DISTRIB_RELEASE | sed -e "s/\..*//g")
        ;;
    "Sisyphus")
        DISTRIB_ID="ALTLinux"
        DISTRIB_RELEASE="Sisyphus"
        DISTRIB_CODENAME="$DISTRIB_RELEASE"
        ;;
545
    "ROSA"|"MOSDesktop"|"MOSPanel")
546 547 548
        DISTRIB_FULL_RELEASE="$DISTRIB_CODENAME"
        DISTRIB_CODENAME="$DISTRIB_RELEASE"
        ;;
549 550 551 552
    "OpenMandrivaLx")
        echo "$PRETTY_NAME" | grep -q "Cooker" && DISTRIB_RELEASE="Cooker"
        echo "$PRETTY_NAME" | grep -q "Rolling" && DISTRIB_RELEASE="Rolling"
        ;;
553 554 555
esac


556
[ -n "$DISTRIB_ID" ] && [ -n "$DISTRIB_RELEASE" ] && return
557 558 559 560


# check via obsoleted ways

561 562
# ALT Linux based
if distro altlinux-release ; then
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
    DISTRIB_ID="ALTLinux"
    # FIXME: fast hack for fallback: 10 -> p10 for /etc/os-release
    DISTRIB_RELEASE="$(echo p$DISTRIB_RELEASE | sed -e 's|\..*||' -e 's|^pp|p|')"
    if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus"
    elif has "ALT p10.* p10 " ; then DISTRIB_RELEASE="p10"
    elif has "ALTServer 10." ; then DISTRIB_RELEASE="p10"
    elif has "ALTServer 9." ; then DISTRIB_RELEASE="p9"
    elif has "ALT c10.* c10 " ; then DISTRIB_RELEASE="c10"
    elif has "ALT p9.* p9 " ; then DISTRIB_RELEASE="p9"
    elif has "ALT 9 SP " ; then DISTRIB_RELEASE="c9"
    elif has "ALT c9f1" ; then DISTRIB_RELEASE="c9f1"
    elif has "ALT MED72 " ; then DISTRIB_RELEASE="p8"
    elif has "ALT 8 SP " ; then DISTRIB_RELEASE="c8"
    elif has "ALT c8.2 " ; then DISTRIB_RELEASE="c8.2"
    elif has "ALT c8.1 " ; then DISTRIB_RELEASE="c8.1"
    elif has "ALT c8 " ; then DISTRIB_RELEASE="c8"
    elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8"
    elif has "Simply Linux 10." ; then DISTRIB_RELEASE="p10"
    elif has "Simply Linux 9." ; then DISTRIB_RELEASE="p9"
    elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8"
    elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7"
    elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6"
    elif has "ALT Linux p8"  ; then DISTRIB_RELEASE="p8"
    elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8"
    elif has "ALT Linux p7"  ; then DISTRIB_RELEASE="p7"
    elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7"
    elif has "ALT Linux t7." ; then DISTRIB_RELEASE="t7"
    elif has "ALT Linux 6." ; then DISTRIB_RELEASE="p6"
    elif has "ALT Linux p6"  ; then DISTRIB_RELEASE="p6"
    elif has "ALT Linux p5"  ; then DISTRIB_RELEASE="p5"
    elif has "ALT Linux 5.1" ; then DISTRIB_RELEASE="5.1"
    elif has "ALT Linux 5.0" ; then DISTRIB_RELEASE="5.0"
    elif has "ALT Linux 4.1" ; then DISTRIB_RELEASE="4.1"
    elif has "ALT Linux 4.0" ; then DISTRIB_RELEASE="4.0"
    elif has "starter kit"   ; then DISTRIB_RELEASE="Sisyphus"
    elif has Citron   ; then DISTRIB_RELEASE="2.4"
    fi
    PRETTY_NAME="$(cat /etc/altlinux-release)"
601 602 603
    DISTRIB_CODENAME="$DISTRIB_RELEASE"
    DISTRO_NAME="$DISTRIB_ID"
    DISTRIB_FULL_RELEASE="$DISTRIB_RELEASE"
604 605

elif distro gentoo-release ; then
606 607 608 609
    DISTRIB_ID="Gentoo"
    MAKEPROFILE=$(readlink $ROOTDIR/etc/portage/make.profile 2>/dev/null) || MAKEPROFILE=$(readlink $ROOTDIR/etc/make.profile)
    DISTRIB_RELEASE=$(basename $MAKEPROFILE)
    echo $DISTRIB_RELEASE | grep -q "[0-9]" || DISTRIB_RELEASE=$(basename "$(dirname $MAKEPROFILE)") #"
610 611

elif distro slackware-version ; then
612 613
    DISTRIB_ID="Slackware"
    DISTRIB_RELEASE="$(grep -Eo '[0-9]+\.[0-9]+' $DISTROFILE)"
614

615
elif distro os-release && is_command tce-ab ; then
616 617 618 619
    # shellcheck disable=SC1090
    . $ROOTDIR/etc/os-release
    DISTRIB_ID="TinyCoreLinux"
    DISTRIB_RELEASE="$VERSION_ID"
620

621
elif distro os-release && is_command xbps-query ; then
622 623 624 625
    # shellcheck disable=SC1090
    . $ROOTDIR/etc/os-release
    DISTRIB_ID="VoidLinux"
    DISTRIB_RELEASE="Live"
626

627
# TODO: use standart /etc/os-release or lsb
628
elif distro arch-release ; then
629 630
    DISTRIB_ID="ArchLinux"
    DISTRIB_RELEASE="rolling"
631

632
# Elbrus
633
elif distro mcst_version ; then
634 635
    DISTRIB_ID="MCST"
    DISTRIB_RELEASE=$(cat "$DISTROFILE" | grep "release" | sed -e "s|.*release \([0-9]*\).*|\1|g") #"
636

637 638
# OpenWrt
elif distro openwrt_release ; then
639 640
    . $DISTROFILE
    DISTRIB_RELEASE=$(cat $ROOTDIR/etc/openwrt_version)
641

642 643
# Debian based
elif distro debian_version ; then
644 645
    DISTRIB_ID="Debian"
    DISTRIB_RELEASE=$(cat $DISTROFILE | sed -e "s/\..*//g")
646 647 648 649


# SUSE based
elif distro SuSe-release || distro SuSE-release ; then
650 651 652 653 654 655 656
    DISTRIB_ID="SUSE"
    DISTRIB_RELEASE=$(cat "$DISTROFILE" | grep "VERSION" | sed -e "s|^VERSION = ||g")
    if   has "SUSE Linux Enterprise Desktop" ; then
        DISTRIB_ID="SLED"
    elif has "SUSE Linux Enterprise Server" ; then
        DISTRIB_ID="SLES"
    fi
657

Vitaly Lipatov's avatar
Vitaly Lipatov committed
658 659 660 661
elif distro redox-release ; then
    DISTRIB_ID="Redox"
    DISTRIB_RELEASE=$(cat $DISTROFILE)

662
# fixme: can we detect by some file?
Vitaly Lipatov's avatar
Vitaly Lipatov committed
663
elif [ "$(uname)" = "FreeBSD" ] ; then
664 665 666
    DISTRIB_ID="FreeBSD"
    UNAME=$(uname -r)
    DISTRIB_RELEASE=$(echo "$UNAME" | grep RELEASE | sed -e "s|\([0-9]\.[0-9]\)-RELEASE|\1|g") #"
667 668

# fixme: can we detect by some file?
Vitaly Lipatov's avatar
Vitaly Lipatov committed
669
elif [ "$(uname)" = "SunOS" ] ; then
670 671
    DISTRIB_ID="SunOS"
    DISTRIB_RELEASE=$(uname -r)
672

Vitaly Lipatov's avatar
Vitaly Lipatov committed
673
# fixme: can we detect by some file?
Vitaly Lipatov's avatar
Vitaly Lipatov committed
674
elif [ "$(uname -s 2>/dev/null)" = "Darwin" ] ; then
675 676
    DISTRIB_ID="MacOS"
    DISTRIB_RELEASE=$(uname -r)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
677

678
# fixme: move to up
679
elif [ "$(uname)" = "Linux" ] && is_command guix ; then
680 681
    DISTRIB_ID="GNU/Linux/Guix"
    DISTRIB_RELEASE=$(uname -r)
682

683
# fixme: move to up
Vitaly Lipatov's avatar
Vitaly Lipatov committed
684
elif [ "$(uname)" = "Linux" ] && [ -x $ROOTDIR/system/bin/getprop ] ; then
685
    DISTRIB_ID="Android"
686 687
    DISTRIB_RELEASE=$(a='' getprop | awk -F": " '/system.build.version.release\]/ { print $2 }' | tr -d '[]' | head -n1)
    [ -n "$DISTRIB_RELEASE" ] || DISTRIB_RELEASE=$(a='' getprop | awk -F": " '/build.version.release/ { print $2 }' | tr -d '[]' | head -n1)
688

Vitaly Lipatov's avatar
Vitaly Lipatov committed
689
elif [ "$(uname -o 2>/dev/null)" = "Cygwin" ] ; then
690 691
        DISTRIB_ID="Cygwin"
        DISTRIB_RELEASE="all"
692
fi
693

694 695
}

696 697
get_uname()
{
698
    tolower "$(uname $1)" | tr -d " \t\r\n"
699 700
}

701 702 703 704 705 706 707
get_glibc_version()
{
    for i in /lib/x86_64-linux-gnu /lib64 /lib/i386-linux-gnu /lib ; do
        [ -x "$ROOTDIR$i/libc.so.6" ] && $ROOTDIR$i/libc.so.6 | head -n1 | grep "version" | sed -e 's|.*version ||' -e 's|\.$||' && return
    done
}

708 709 710 711
get_base_os_name()
{
local DIST_OS
# Resolve the os
712
DIST_OS="$(get_uname -s)"
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
case "$DIST_OS" in
    'sunos')
        DIST_OS="solaris"
        ;;
    'hp-ux' | 'hp-ux64')
        DIST_OS="hpux"
        ;;
    'darwin' | 'oarwin')
        DIST_OS="macosx"
        ;;
    'unix_sv')
        DIST_OS="unixware"
        ;;
    'freebsd' | 'openbsd' | 'netbsd')
        DIST_OS="freebsd"
        ;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
729 730 731
    'Redox')
        DIST_OS="redox"
        ;;
732 733 734 735
esac
echo "$DIST_OS"
}

736

737 738
get_arch()
{
739
[ -n "$DIST_ARCH" ] && return 0
740
# Resolve the architecture
741
DIST_ARCH="$(get_uname -m)"
742
case "$DIST_ARCH" in
743
    'ia32' | 'i386' | 'i486' | 'i586' | 'i686')
744 745
        DIST_ARCH="x86"
        ;;
746 747 748
    'amd64' | 'x86_64')
        DIST_ARCH="x86_64"
        ;;
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
    'ia64' | 'ia-64')
        DIST_ARCH="ia64"
        ;;
    'ip27' | 'mips')
        DIST_ARCH="mips"
        ;;
    'powermacintosh' | 'power' | 'powerpc' | 'power_pc' | 'ppc64')
        DIST_ARCH="ppc"
        ;;
    'pa_risc' | 'pa-risc')
        DIST_ARCH="parisc"
        ;;
    'sun4u' | 'sparcv9')
        DIST_ARCH="sparc"
        ;;
    '9000/800')
        DIST_ARCH="parisc"
        ;;
767 768 769 770 771 772
    'arm64' | 'aarch64')
        DIST_ARCH='aarch64'
        ;;
    armv7*)
        # TODO: use uname only
        # uses binutils package
Vitaly Lipatov's avatar
Vitaly Lipatov committed
773
        if is_command readelf && [ -z "$(a='' readelf -A /proc/self/exe | grep Tag_ABI_VFP_args)" ] ; then
774 775 776 777 778 779 780 781 782
            DIST_ARCH="armel"
        else
            DIST_ARCH="armhf"
        fi
        ;;
esac
echo "$DIST_ARCH"
}

783 784 785 786
get_debian_arch()
{
    local arch="$(get_arch)"
    case $arch in
787
    'x86')
788 789 790
        arch='i386' ;;
    'x86_64')
        arch='amd64' ;;
791 792
    'aarch64')
        arch='arm64' ;;
793 794 795 796
    esac
    echo "$arch"
}

797 798 799 800 801
get_distro_arch()
{
    local arch="$(get_arch)"
    case "$(pkgtype)" in
        rpm)
802 803 804 805
            case $arch in
            'x86')
                arch='i586' ;;
            esac
806 807
            ;;
        deb)
808 809
            get_debian_arch
            return
810 811 812 813 814
            ;;
    esac
    echo "$arch"
}

815 816 817
get_bit_size()
{
local DIST_BIT
818

819
DIST_BIT="$(a= getconf LONG_BIT 2>/dev/null)"
820 821
if [ -n "$DIST_BIT" ] ; then
    echo "$DIST_BIT"
822
    return
823 824 825 826
fi

# Try detect arch size by arch name
case "$(get_uname -m)" in
827 828 829
    'amd64' | 'ia64' | 'x86_64' | 'ppc64')
        DIST_BIT="64"
        ;;
830 831 832
    'aarch64')
        DIST_BIT="64"
        ;;
833 834 835
    'e2k')
        DIST_BIT="64"
        ;;
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
#    'pa_risc' | 'pa-risc') # Are some of these 64bit? Least not all...
#       BIT="64"
#        ;;
    'sun4u' | 'sparcv9') # Are all sparcs 64?
        DIST_BIT="64"
        ;;
#    '9000/800')
#       DIST_BIT="64"
#        ;;
    *) # In any other case default to 32
        DIST_BIT="32"
        ;;
esac
echo "$DIST_BIT"
}

852
# TODO: check before calc
853 854 855
get_memory_size()
{
    local detected=""
856
    local divider="1"
857 858 859
    local DIST_OS="$(get_base_os_name)"
    case "$DIST_OS" in
        macosx)
860 861
            detected="$(a='' sysctl hw.memsize | sed 's/hw.memsize: //')"
            divider="1024/1024"
862 863
            ;;
        freebsd)
864 865
            detected="$(a='' sysctl hw.physmem | sed 's/hw.physmem: //')"
            divider="1024/1024"
866 867
            ;;
        linux)
868 869
            detected="$(cat /proc/meminfo 2>/dev/null | grep 'MemTotal' | awk '{print $2}')"
            divider="1024"
870
            ;;
871
        solaris)
872
            detected=$(a='' prtconf | grep Memory | sed -e "s|Memory size: \([0-9][0-9]*\) Megabyte.*|\1|") #"
873
            divider="1"
874 875 876
            ;;
#        *)
#            fatal "Unsupported OS $DIST_OS"
877 878
    esac

879
    [ -n "$detected" ] || detected=0
880
    echo "$(($detected/$divider))"
881 882
}

883 884 885 886 887
print_name_version()
{
    [ -n "$DISTRIB_RELEASE" ] && echo $DISTRIB_ID/$DISTRIB_RELEASE || echo $DISTRIB_ID
}

888 889 890 891 892 893
get_core_count()
{
    local detected=""
    local DIST_OS="$(get_base_os_name)"
    case "$DIST_OS" in
        macos|freebsd)
894
            detected=$(a= sysctl hw.ncpu | awk '{print $2}')
895 896 897 898 899
            ;;
        linux)
            detected=$(grep -c "^processor" /proc/cpuinfo)
            ;;
        solaris)
900
            detected=$(a= prtconf | grep -c 'cpu[^s]')
901 902
            ;;
        aix)
903
            detected=$(a= lsdev -Cc processor -S A | wc -l)
904 905 906 907 908 909 910 911 912
            ;;
#        *)
#            fatal "Unsupported OS $DIST_OS"
    esac

    [ -n "$detected" ] || detected=0
    echo $detected
}

913 914 915 916 917
get_core_mhz()
{
    cat /proc/cpuinfo | grep "cpu MHz" | head -n1 | cut -d':' -f2 | cut -d' ' -f2 | cut -d'.' -f1
}

918

919 920 921
get_virt()
{
    local VIRT
922
    if is_command systemd-detect-virt ; then
Vitaly Lipatov's avatar
Vitaly Lipatov committed
923
        VIRT="$(a='' systemd-detect-virt)"
924 925 926 927
        [ "$VIRT" = "none" ] && echo "(host system)" && return
        [ -z "$VIRT" ] && echo "(unknown)" && return
        echo "$VIRT" && return
    fi
928 929 930 931 932

    # TODO: use virt-what under root

    # inspired by virt_what
    if [ -d "/proc/vz" -a ! -d "/proc/bc" ]; then
933 934
        echo "openvz" && return
    fi
935 936 937 938 939

    if [ -r "/sys/bus/xen" ] ; then
        echo "xen" && return
    fi

940
    # use util-linux
941
    if LC_ALL=C a= lscpu 2>/dev/null | grep "Hypervisor vendor:" | grep -q "KVM" ; then
942 943 944
        echo "kvm" && return
    fi

945 946 947 948
    echo "(unknown)"
    # TODO: check for openvz
}

949 950 951 952 953 954 955
get_init_process_name()
{
    [ ! -f /proc/1/comm ] && echo "(unknown)" && return 1
    cat /proc/1/comm | head -n1
    #ps --no-headers -o comm 1
}

956 957 958 959
# https://unix.stackexchange.com/questions/196166/how-to-find-out-if-a-system-uses-sysv-upstart-or-systemd-initsystem
get_service_manager()
{
    [ -d /run/systemd/system ] && echo "systemd" && return
960 961
    # TODO
    #[ -d /usr/share/upstart ] && echo "upstart" && return
962
    is_command systemctl && [ "$(get_init_process_name)" = 'systemd' ] && echo "systemd" && return
963
    [ -d /etc/init.d ] && echo "sysvinit" && return
964
    get_init_process_name
965 966
}

967 968 969 970 971
filter_duplicated_words()
{
    echo "$*" | xargs -n1 echo | uniq | xargs -n100 echo
}

972 973
print_pretty_name()
{
974 975 976 977
    if [ -z "$PRETTY_NAME" ] ; then
        PRETTY_NAME="$DISTRIB_ID $DISTRIB_RELEASE"
    fi

978 979 980 981
    if ! echo "$PRETTY_NAME" | grep -q "$DISTRIB_FULL_RELEASE" ; then
        PRETTY_NAME="$PRETTY_NAME ($DISTRIB_FULL_RELEASE)"
    fi

982 983 984 985
    if ! echo "$PRETTY_NAME" | grep -q "$DISTRIB_RELEASE" ; then
        PRETTY_NAME="$PRETTY_NAME ($DISTRIB_RELEASE)"
    fi

986
    echo "$(filter_duplicated_words "$PRETTY_NAME")"
987
}
988 989 990

print_total_info()
{
991
local orig=''
992
[ -n "$BUILD_ID" ] && [ "$DISTRIB_FULL_RELEASE" != "$BUILD_ID" ] && orig=" (orig. $BUILD_ID)"
993 994
local EV=''
[ -n "$EPMVERSION" ] && EV="(EPM version $EPMVERSION) "
995
cat <<EOF
996
distro_info v$PROGVERSION $EV: Copyright © 2007-2025 Etersoft
997

998 999
                       Pretty name (--pretty): $(print_pretty_name)
           (--distro-name / --distro-version): $DISTRO_NAME / $DISTRIB_FULL_RELEASE$orig
1000 1001 1002 1003
         Base distro name (-d) / version (-v): $(print_name_version)
     Vendor distro name (-s) / Repo name (-r): $(pkgvendor) / $(print_repo_name)
                 Package manager/type (-g/-p): $(pkgmanager) / $(pkgtype)
            Base OS name (-o) / CPU arch (-a): $(get_base_os_name) $(get_arch)
1004
                 CPU norm register size  (-b): $(get_bit_size) bit
1005 1006
                          Virtualization (-i): $(get_virt)
                        CPU Cores/MHz (-c/-z): $(get_core_count) / $(get_core_mhz) MHz
1007
                      System memory size (-m): $(get_memory_size) MiB
1008
                 Running service manager (-y): $(get_service_manager)
1009
            Bug report URL (--bug-report-url): $(print_bug_report_url)
1010 1011

(run with -h to get help)
1012
EOF
1013 1014
}

1015 1016 1017 1018 1019 1020
print_help()
{
    echo "distro_info v$PROGVERSION - distro information retriever"
    echo "Usage: distro_info [options] [SystemName/Version]"
    echo "Options:"
    echo " -h | --help            - this help"
1021
    echo " -a                     - print hardware architecture (use --distro-arch for distro depended arch name)"
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
    echo " -b                     - print size of arch bit (32/64)"
    echo " -c                     - print number of CPU cores"
    echo " -i                     - print virtualization type"
    echo " -m                     - print system memory size (in MB)"
    echo " -y|--service-manager   - print running service manager"
    echo " -z                     - print current CPU MHz"
    echo " --glibc-version        - print system glibc version"
    echo
    echo " -d|--base-distro-name  - print distro id (short distro name)"
    echo " -e                     - print full name of distro with version"
    echo " -o | --os-name         - print base OS name"
1033 1034
    echo " -p | --package-type    - print type of the packaging system (f.i., apt-dpkg)"
    echo " -g                     - print name of the packaging system (f.i., deb)"
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
    echo " -s|-n|--vendor-name    - print name of the distro family (vendor name) (ubuntu for all Ubuntu family, alt for all ALT family) (see _vendor macros in rpm)"
    echo " --pretty|--pretty-name - print pretty distro name"
    echo " -v | --base-version    - print version of the distro"
    echo " --distro-name          - print distro name"
    echo " --distro-version       - print full version of the distro"
    echo " --full-version         - print full version of the distro"
    echo " --codename (obsoleted) - print distro codename (focal for Ubuntu 20.04)"
    echo " -r|--repo-name         - print repository name (focal for Ubuntu 20.04)"
    echo " --build-id             - print a string uniquely identifying the system image originally used as the installation base"
    echo " -V                     - print the utility version"
    echo "Run without args to print all information."
}

1048 1049 1050
# print code for eval with names for eepm
print_eepm_env()
{
1051
cat <<EOF
1052
# -d | --base-distro-name
1053
DISTRNAME="$(echo $DISTRIB_ID)"
1054
# -v | --base-version
1055
DISTRVERSION="$(echo "$DISTRIB_RELEASE")"
1056
# distro dependent arch
1057
DISTRARCH="$(get_distro_arch)"
1058
# -s | --vendor-name
1059
BASEDISTRNAME=$(pkgvendor)
1060
# --repo-name
1061
DISTRREPONAME=$(print_repo_name)
1062

1063
# -a
1064
SYSTEMARCH="$(get_arch)"
1065
# -y | --service-manager
1066
DISTRCONTROL="$(get_service_manager)"
1067
# -g
1068
PMTYPE="$(pkgmanager)"
1069
# -p | --package-type
1070
PKGFORMAT=$(pkgtype)
1071
# -m
1072
DISTRMEMORY="$(get_memory_size)"
1073 1074

# TODO: remove?
1075 1076
PKGVENDOR=$(pkgvendor)
RPMVENDOR=$(pkgvendor)
1077

1078
EOF
1079 1080

}
1081

1082
override_distrib "$DISTRNAMEOVERRIDE"
1083

1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
if [ -n "$*" ] ; then
    eval lastarg=\${$#}
    case "$lastarg" in
        -*)
            ;;
        *)
            override_distrib "$lastarg"
            # drop last arg
            set -- "${@:1:$(($#-1))}"
            ;;
    esac
fi
1096

1097
# if without override
1098
if [ -z "$DISTRIB_ID" ] ; then
1099 1100 1101 1102
    fill_distr_info
    [ -n "$DISTRIB_ID" ] || DISTRIB_ID="Generic"
fi

1103 1104 1105 1106
if [ -z "$1" ] ; then
    print_total_info
    exit
fi
1107

1108
while [ -n "$1" ] ; do
1109
case "$1" in
1110
    -h|--help)
1111
        print_help
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141
        exit 0
        ;;
    -p|--package-type)
        pkgtype
        ;;
    -g)
        pkgmanager
        ;;
    --pretty|--pretty-name)
        print_pretty_name
        ;;
    --distro-arch)
        get_distro_arch
        ;;
    --debian-arch)
        get_debian_arch
        ;;
    --glibc-version)
        get_glibc_version
        ;;
    -d|--base-distro-name)
        echo $DISTRIB_ID
        ;;
    --distro-name)
        echo $DISTRO_NAME
        ;;
    --codename)
        print_codename
        ;;
    -a)
1142 1143 1144 1145 1146
        if [ -n "$DIST_ARCH" ] ; then
            echo "$DIST_ARCH"
        else
            get_arch
        fi
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192
        ;;
    -b)
        get_bit_size
        ;;
    -c)
        get_core_count
        ;;
    -z)
        get_core_mhz
        ;;
    -i)
        get_virt
        ;;
    -m)
        get_memory_size
        ;;
    -o|--os-name)
        get_base_os_name
        ;;
    -r|--repo-name)
        print_repo_name
        ;;
    --build-id)
        echo "$BUILD_ID"
        ;;
    -v|--base-version)
        echo "$DISTRIB_RELEASE"
        ;;
    --full-version|--distro-version)
        echo "$DISTRIB_FULL_RELEASE"
        ;;
    --bug-report-url)
        print_bug_report_url
        ;;
    -s|-n|--vendor-name)
        pkgvendor
        ;;
    -y|--service-manager)
        get_service_manager
        ;;
    -V)
        echo "$PROGVERSION"
        ;;
    -e)
        print_name_version
        ;;
1193 1194 1195 1196
    --print-eepm-env)
        print_eepm_env
        exit 0
        ;;
1197 1198
    -*)
        echo "Unsupported option $1" >&2
1199 1200
        # print empty line in any case
        echo
1201 1202
        exit 1
        ;;
1203
esac
1204 1205
shift
done