Proyecto

General

Perfil

      • Registrar

        install

        Arturo Martin, 2024-05-30 10:46

         
        1
        #!/bin/sh
        
        2
        # Copyright 2018-2024 Alkis Georgopoulos <github.com/alkisg>
        
        3
        # SPDX-License-Identifier: GPL-3.0-or-later
        
        4
        
            
        5
        usage() {
        
        6
            printf "Usage: %s [OPTIONS] [COMMAND]
        
        7
        
            
        8
        Install the drivers for the BrosTrend AC1L/AC3L/AC5L, AX1L/AX4L/AX5L adapters.
        
        9
        The main difficulty is in detecting the appropriate kernel *headers* package.
        
        10
        
            
        11
        Options:
        
        12
            -h  Show this help message.
        
        13
            -p  Pause on exit.
        
        14
            -t  Gather troubleshoting information.
        
        15
        " "$0"
        
        16
        }
        
        17
        
            
        18
        bold() {
        
        19
            if [ "$_PRINTBOLD_FIRST_TIME" != 1 ]; then
        
        20
                _PRINTBOLD_FIRST_TIME=1
        
        21
                _BOLD_FACE=$(tput bold 2>/dev/null) || true
        
        22
                _NORMAL_FACE=$(tput sgr0 2>/dev/null) || true
        
        23
            fi
        
        24
            if [ "$1" = "-n" ]; then
        
        25
                shift
        
        26
                printf "%s" "${_BOLD_FACE}$*${_NORMAL_FACE}"
        
        27
            else
        
        28
                printf "%s\n" "${_BOLD_FACE}$*${_NORMAL_FACE}"
        
        29
            fi
        
        30
        }
        
        31
        
            
        32
        # For the external tools we need that are also provided by busybox,
        
        33
        # if some tool doesn't exist, create a namesake function that calls busybox.
        
        34
        # `/usr/lib/initramfs-tools/bin/busybox` shows the smallest list of tools.
        
        35
        busybox_fallbacks() {
        
        36
            local busybox tool
        
        37
        
            
        38
            busybox=$(command -v busybox)
        
        39
            # Ubuntu chroots ship with a "busybox-initramfs" minimal package
        
        40
            if [ -z "$busybox" ] && [ -x /usr/lib/initramfs-tools/bin/busybox ]; then
        
        41
                busybox=/usr/lib/initramfs-tools/bin/busybox
        
        42
            fi
        
        43
            test -n "$busybox" || return 0
        
        44
            for tool in awk blockdev cat chgrp chmod chown chroot chvt cp \
        
        45
                cpio cut date df env expr find getopt grep head hostname id \
        
        46
                insmod ionice ip kill killall ln logger losetup ls lsmod \
        
        47
                mkdir mktemp modprobe mount mv nc netstat pidof ping \
        
        48
                poweroff ps pwd readlink rm rmdir rmmod sed setsid sleep sort \
        
        49
                swapoff swapon switch_root sync tee touch tr truncate umount \
        
        50
                uname wc; do
        
        51
                # Periodically, prefix a "true" to the following line and test all
        
        52
                # applets to see if we are indeed compatible with the busybox syntax
        
        53
                ! is_command "$tool" || continue
        
        54
                eval "$tool() {
        
        55
            $busybox $tool \"\$@\"
        
        56
        }"
        
        57
            done
        
        58
        }
        
        59
        
            
        60
        # Set $_DRIVER, based on the script filename, or the inserted adapter,
        
        61
        # or the user input. It may also be set in the environment.
        
        62
        select_driver() {
        
        63
            local fname product _dummy choice
        
        64
        
            
        65
            fname=${0##*/}
        
        66
            fname=${fname%.sh}
        
        67
            case "$fname" in
        
        68
            8812au | 88x2bu | 8821cu | 8852bu) _DRIVER="rtl$fname" ;;
        
        69
            aic8800) _DRIVER=$fname ;;
        
        70
            esac
        
        71
            while [ -z "$_DRIVER" ]; do
        
        72
                while read -r product _dummy; do
        
        73
                    case "$product" in
        
        74
                    0bda:8812) _DRIVER=rtl8812au ;;
        
        75
                    0bda:b812) _DRIVER=rtl88x2bu ;;
        
        76
                    0bda:c811) _DRIVER=rtl8821cu ;;
        
        77
                    0bda:1a2b)
        
        78
                        _DRIVER=rtl8852bu
        
        79
                        bold "Switching the adapter from storage to WLAN mode"
        
        80
                        # Background it as it can take up to 30 seconds in a VM
        
        81
                        rw usb_modeswitch -KQ -v 0bda -p 1a2b &
        
        82
                        ;;
        
        83
                    0bda:b832) _DRIVER=rtl8852bu ;;
        
        84
                    a69c:5721)
        
        85
                        _DRIVER=aic8800
        
        86
                        bold "Switching the adapter from storage to WLAN mode"
        
        87
                        # Background it as it can take up to 30 seconds in a VM
        
        88
                        rw usb_modeswitch -KQ -v a69c -p 5721 &
        
        89
                        ;;
        
        90
                    368b:88df) _DRIVER=aic8800 ;;
        
        91
                    esac
        
        92
                done <<EOF
        
        93
        $(lsusb_)
        
        94
        EOF
        
        95
                test -n "$_DRIVER" && break
        
        96
                bold "Could not detect the adapter!"
        
        97
                echo "Please insert the BrosTrend Wi-Fi adapter into a USB slot
        
        98
        and press [Enter] to continue.
        
        99
        If you don't have the adapter currently, you may type:
        
        100
          (a) to install the 8812au driver for the old AC1L/AC3L models before 2019, or
        
        101
          (b) to install the 88x2bu driver for the new AC1L/AC3L version 2 models, or
        
        102
          (c) to install the 8821cu driver for the AC5L model, or
        
        103
          (d) to install the 8852bu driver for the AX1L/AX4L models, or
        
        104
          (e) to install the aic8800 driver for the AX5L model,
        
        105
          (q) to quit without installing a driver"
        
        106
                bold -n "Please type your choice, or [Enter] to autodetect: "
        
        107
                read -r choice
        
        108
                case "$choice" in
        
        109
                a) _DRIVER=rtl8812au ;;
        
        110
                b) _DRIVER=rtl88x2bu ;;
        
        111
                c) _DRIVER=rtl8821cu ;;
        
        112
                d) _DRIVER=rtl8852bu ;;
        
        113
                e) _DRIVER=aic8800 ;;
        
        114
                q) die "Aborted" ;;
        
        115
                esac
        
        116
            done
        
        117
        }
        
        118
        
            
        119
        detect_package_manager() {
        
        120
            for _PM in apt-get dnf eopkg pacman pkgtool ppm swupd yum xbps-install zypper unknown; do
        
        121
                if is_command "$_PM"; then
        
        122
                    if [ "$_PM" = "apt-get" ] && ! is_command dpkg && is_command rpm; then
        
        123
                        # ALT, PCLinuxOS, Vine: https://en.wikipedia.org/wiki/APT-RPM
        
        124
                        _PM=apt-rpm
        
        125
                    fi
        
        126
                    break
        
        127
                fi
        
        128
            done
        
        129
            bold "Package manager is: $_PM"
        
        130
        }
        
        131
        
            
        132
        # Output a message to stderr and abort execution
        
        133
        die() {
        
        134
            bold "$@" >&2
        
        135
            pause_exit 1
        
        136
        }
        
        137
        
            
        138
        # Download a file from the Internet
        
        139
        download() {
        
        140
            if is_command wget; then
        
        141
                re wget --no-check-certificate -nv "$@"
        
        142
            elif is_command curl; then
        
        143
                re curl --insecure -O "$@"
        
        144
            elif is_command busybox; then
        
        145
                # busybox wget supports --no-check-certificate since 20.04, no point
        
        146
                re busybox wget -nv "$@"
        
        147
            else
        
        148
                die "Please install wget or curl and then re-run the installer"
        
        149
            fi
        
        150
        }
        
        151
        
            
        152
        install_debian_prerequisites() {
        
        153
            local kernel header headers
        
        154
        
            
        155
            rw apt-get update
        
        156
            # If the appropriate headers are already installed, return
        
        157
            test -d "/lib/modules/$(uname -r)/build" && return 0
        
        158
        
            
        159
            # Possible image metapackage names:
        
        160
            # Ubuntu: https://packages.ubuntu.com/source/focal/linux-meta
        
        161
            # E.g. linux-image-generic, linux-image-lowlatency-hwe-18.04
        
        162
            # Debian: https://packages.debian.org/source/buster/linux-latest
        
        163
            # E.g. linux-image-686, linux-image-amd64, linux-image-armmp
        
        164
            # Proxmox: pve-kernel-5.4, pve-kernel5.15, pve-headers
        
        165
            # Raspberry Pi OS: raspberrypi-kernel
        
        166
            # OSMC: rbp2-kernel-osmc, rbp2-image-4.19.55-6-osmc, rbp2-headers-4.19.55-6-osmc
        
        167
            # ODROID-XU4: linux-odroid-5422 (Bionic, 4.14.165-172, armv7l, includes headers)
        
        168
        
            
        169
            headers=""
        
        170
            # We can't use `dpkg -S .../modules.builtin` as -hwe are metapackages.
        
        171
            # So we use `dpkg -l linux-image-[^.][^.][^.]*` to avoid linux-image-5.11
        
        172
            # but include linux-image-hwe-18.04.
        
        173
            # The [hi] part is for held kernel packages, e.g. moodleaudio.org
        
        174
            for kernel in $(dpkg -l 'linux-image[^.][^.][^.]*' 'pve-kernel*[^a-z]' raspberrypi-kernel 2>/dev/null |
        
        175
                awk '/^[hi]i/ { print $2 }'); do
        
        176
                case "$kernel" in
        
        177
                pve-kernel*)
        
        178
                    header=pve-headers
        
        179
                    ;;
        
        180
                raspberrypi-kernel)
        
        181
                    header=raspberrypi-kernel-headers
        
        182
                    ;;
        
        183
                *)
        
        184
                    header=$(echo "$kernel" | sed 's/image/headers/')
        
        185
                    ;;
        
        186
                esac
        
        187
                if apt-cache policy "$header" | grep -q '[0-9]'; then
        
        188
                    headers="$headers $header"
        
        189
                fi
        
        190
            done
        
        191
            if [ -n "$headers" ]; then
        
        192
                bold "Installing kernel headers:$headers"
        
        193
                re apt-get install --yes $headers
        
        194
            else
        
        195
                request_info "Couldn't detect the appropriate kernel headers package!" \
        
        196
                    dpkg -S "/lib/modules/$(uname -r)"
        
        197
            fi
        
        198
        }
        
        199
        
            
        200
        install_driver() {
        
        201
            local module reinstall ver ikd
        
        202
        
            
        203
            case "$_DRIVER" in
        
        204
            rtl*) module=${_DRIVER#rtl} ;;
        
        205
            *) module=aic8800_fdrv ;;
        
        206
            esac
        
        207
            bold "Downloading the $_DRIVER driver"
        
        208
            re cd "$(mktemp -d)"
        
        209
            # Avoid the "Download is performed unsandboxed" apt warning
        
        210
            re chmod 755 .
        
        211
            download "https://linux.brostrend.com/$_DRIVER-dkms.deb"
        
        212
            bold "Installing and compiling the driver"
        
        213
            case "$_PM" in
        
        214
            apt-get)
        
        215
                # Prefer apt, but fall back to dpkg if necessary
        
        216
                if dpkg --compare-versions "$(dpkg-query -W apt | awk '{ print $2 }')" gt 1.2; then
        
        217
                    # Avoid "Internal Error, No filename for..." error on ^iF
        
        218
                    if dpkg -l "$_DRIVER-dkms" | grep -q ^ii; then
        
        219
                        reinstall=--reinstall
        
        220
                    else
        
        221
                        unset reinstall
        
        222
                    fi
        
        223
                    # We want --no-install-recommends here because dkms in Debian
        
        224
                    # recommends a lot of kernel header packages that we may not require.
        
        225
                    # Caution, linuxmint uses a wrapper that can run `apt install --yes`
        
        226
                    # but it doesn't understand `apt --yes install`. Meh.
        
        227
                    re apt install $reinstall --yes --no-install-recommends \
        
        228
                        "./$_DRIVER-dkms.deb"
        
        229
                else
        
        230
                    # The downside of using dpkg instead of apt is that dkms etc
        
        231
                    # will be marked as "manually installed".
        
        232
                    re apt-get install --yes --no-install-recommends \
        
        233
                        bc dkms libc6-dev linux-libc-dev
        
        234
                    re dpkg -i "./$_DRIVER-dkms.deb"
        
        235
                fi
        
        236
                ;;
        
        237
            *)
        
        238
                re ar x "$_DRIVER-dkms.deb"
        
        239
                re tar xf data.tar.gz
        
        240
                ver=$(echo usr/src/*-*)
        
        241
                ver=${ver##*-}
        
        242
                re rm -rf "/usr/src/$_DRIVER-$ver"
        
        243
                re mv "usr/src/$_DRIVER-$ver" /usr/src/
        
        244
                re cd "/usr/src/$_DRIVER-$ver"
        
        245
                if is_command dkms; then
        
        246
                    dkms remove -m "$_DRIVER" -v "$ver" --all 2>/dev/null
        
        247
                    rw dkms add -m "$_DRIVER" -v "$ver"
        
        248
                    re dkms build -m "$_DRIVER" -v "$ver"
        
        249
                    re dkms install -m "$_DRIVER" -v "$ver"
        
        250
                else
        
        251
                    bold "Compiling without dkms..."
        
        252
                    re make
        
        253
                    re make install
        
        254
                fi
        
        255
                # Install the conf file which blacklists the in-kernel drivers
        
        256
                if [ -L "/etc/modprobe.d/$module.conf" ]; then
        
        257
                    rm -f "/etc/modprobe.d/$module.conf"
        
        258
                fi
        
        259
                link="/usr/src/$_DRIVER-$ver/$module.conf"
        
        260
                if [ -f "$link" ] &&
        
        261
                    [ -d /etc/modprobe.d ] &&
        
        262
                    [ ! -e "/etc/modprobe.d/$_DRIVER.conf" ]; then
        
        263
                    re ln -s "$link" /etc/modprobe.d/
        
        264
                fi
        
        265
                ;;
        
        266
            esac
        
        267
            # Unload the competing in-kernel drivers
        
        268
            case "$_DRIVER" in
        
        269
            rtl88x2bu) ikd=rtw88_8822bu ;;
        
        270
            rtl8821cu) ikd=rtw88_8821cu ;;
        
        271
            *) ikd= ;;
        
        272
            esac
        
        273
            if [ -n "$ikd" ] && [ -d "/sys/module/$ikd" ]; then
        
        274
                bold "Unloading the $ikd in-kernel driver"
        
        275
                if ! timeout 10 modprobe -r "$ikd"; then
        
        276
                    bold "Failed to unload the $ikd in-kernel driver, PLEASE REBOOT"
        
        277
                fi
        
        278
            fi
        
        279
            re modprobe "$module"
        
        280
        }
        
        281
        
            
        282
        # Install missing packages from the ones specified
        
        283
        # $1: package manager command
        
        284
        # $*: packages
        
        285
        # If "cmd:package" is passed and missing, return "package".
        
        286
        # If "headers:package" is passed, check for the running kernel headers.
        
        287
        inmp() {
        
        288
            local pmcmd
        
        289
            local var cmd package
        
        290
            local list
        
        291
        
            
        292
            pmcmd=$1
        
        293
            shift
        
        294
            list=""
        
        295
            for var; do
        
        296
                IFS=":" read -r cmd package <<EOF
        
        297
        $var
        
        298
        EOF
        
        299
                package=${package:-$cmd}
        
        300
                if [ "$cmd" = headers ]; then
        
        301
                    if [ ! -d "/lib/modules/$(uname -r)/build" ]; then
        
        302
                        list="$list $package"
        
        303
                    fi
        
        304
                elif ! is_command "$cmd"; then
        
        305
                    list="$list $package"
        
        306
                fi
        
        307
            done
        
        308
            if [ -n "$list" ]; then
        
        309
                bold "Running: $pmcmd$list"
        
        310
                if [ "$pmcmd" = "unknown" ]; then
        
        311
                    request_info "Unsupported distribution!
        
        312
        Install dependencies manually: ar bc gcc make tar linux-headers
        
        313
        Please see: https://linux.brostrend.com/supported-distributions" \
        
        314
                        cat /etc/os-release
        
        315
                else
        
        316
                    re $pmcmd $list
        
        317
                fi
        
        318
            fi
        
        319
        }
        
        320
        
            
        321
        # The prerequisites are:
        
        322
        # ar:binutils bc elfutils-libelf-devel gcc make tar headers:kernel-devel
        
        323
        # elfutils-libelf-devel too for rpm dists, see https://bugs.debian.org/886474
        
        324
        # dkms satisfies all of them except for bc
        
        325
        install_prerequisites() {
        
        326
            local var
        
        327
        
            
        328
            bold "Installing prerequisites"
        
        329
            case "$_PM" in
        
        330
            # TODO: see variations in https://github.com/morrownr/88x2bu-20210702
        
        331
            apt-get | apt-rpm)
        
        332
                install_debian_prerequisites
        
        333
                ;;
        
        334
            dnf | yum | zypper)
        
        335
                # Examples of `rpm -qf "/boot/vmlinuz-$(uname -r)"`:
        
        336
                # CentOS Linux 8: kernel-core-4.18.0-348.7.1.el8_5.x86_64
        
        337
                # CentOS Linux 8 -lt: kernel-lt-core-5.4.240-1.el8.elrepo.x86_64
        
        338
                # fedora-37: kernel-core-6.1.18-200.fc37.x86_64
        
        339
                # fedora-38: kernel-modules-core-6.2.11-300.fc38.x86_64
        
        340
                # openSUSE Leap 15.3: kernel-default-5.3.18-150300.59.106.1.x86_64
        
        341
                # Transform them to e.g.: kernel-devel, kernel-lt-devel, -ml, -uek,
        
        342
                # kernel-default-devel
        
        343
                var=$(rpm -qf "/boot/vmlinuz-$(uname -r)") ||
        
        344
                    request_info "Unknown kernel"
        
        345
                var=$(echo "$var" | grep -o 'kernel-[-[:alpha:]]*')
        
        346
                var=${var%core-}
        
        347
                var=${var%modules-}
        
        348
                var="${var}devel"
        
        349
                if [ "$_PM" = "zypper" ]; then
        
        350
                    inmp "zypper install -y" bc dkms "headers:$var"
        
        351
                else
        
        352
                    # RHEL-based distributions might not provide dkms
        
        353
                    if "$_PM" list dkms >/dev/null 2>&1; then
        
        354
                        inmp "$_PM install -y" bc dkms "headers:$var"
        
        355
                    else
        
        356
                        inmp "$_PM install -y" ar:binutils bc :elfutils-libelf-devel gcc make tar "headers:$var"
        
        357
                    fi
        
        358
                fi
        
        359
                ;;
        
        360
            eopkg)
        
        361
                re eopkg update-repo
        
        362
                inmp "eopkg install" ar:binutils bc gcc make tar headers:linux-current-headers
        
        363
                ;;
        
        364
            pacman)
        
        365
                # In Manjaro, select the current kernel, not the old linux316-headers:
        
        366
                inmp "pacman -Sy" bc dkms headers:linux-headers
        
        367
                ;;
        
        368
            swupd)
        
        369
                # https://docs.01.org/clearlinux/latest/guides/kernel/kernel-modules-dkms.html
        
        370
                var="$(uname -r)"
        
        371
                var=${var##*.}
        
        372
                inmp "swupd bundle-add" bc dkms:"kernel-$var-dkms"
        
        373
                ;;
        
        374
            xbps-install)
        
        375
                inmp "xbps-install -S" bc dkms
        
        376
                ;;
        
        377
            *)
        
        378
                inmp "unknown" bc ar bc gcc make tar headers
        
        379
                ;;
        
        380
            esac
        
        381
        }
        
        382
        
            
        383
        # Check if parameter is a command; `command -v` isn't allowed by POSIX
        
        384
        is_command() {
        
        385
            local fun
        
        386
        
            
        387
            if [ -z "$_IS_COMMAND" ]; then
        
        388
                command -v is_command >/dev/null ||
        
        389
                    die "Your shell doesn't support command -v"
        
        390
                _IS_COMMAND=1
        
        391
            fi
        
        392
            for fun in "$@"; do
        
        393
                command -v "$fun" >/dev/null || return $?
        
        394
            done
        
        395
        }
        
        396
        
            
        397
        # Return true if the kernel is at least that version
        
        398
        kver() {
        
        399
            if [ -z "$_UNAME_R" ]; then
        
        400
                _UNAME_R=$(uname -r)
        
        401
            fi
        
        402
            test "$(printf "%s\n%s\n" "$_UNAME_R" "$1" | sort -rV | head -n1)" = "$_UNAME_R" ||
        
        403
                return $?
        
        404
        }
        
        405
        
            
        406
        # Implement lsusb as it isn't preinstalled in some distributions
        
        407
        # Return only the Brostrend devices
        
        408
        # Typical lsusb descriptions (/var/lib/usbutils/usb.ids):
        
        409
        # AC1,3Lv1: Bus 003 Device 008: ID 0bda:8812 Realtek Semiconductor Corp.
        
        410
        #           RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter
        
        411
        # AC1,3Lv2: Bus 003 Device 007: ID 0bda:b812 Realtek Semiconductor Corp.
        
        412
        #           RTL88x2bu [AC1200 Techkey]
        
        413
        # AC5L:     Bus 003 Device 027: ID 0bda:c811 Realtek Semiconductor Corp.
        
        414
        #           802.11ac NIC
        
        415
        # AX1Lst:   Bus 003 Device 027: ID 0bda:1a2b Realtek Semiconductor Corp.
        
        416
        #           RTL8188GU 802.11n WLAN Adapter (Driver CDROM Mode)
        
        417
        # AX1,4L:   Bus 003 Device 027: ID 0bda:b832 Realtek Semiconductor Corp.
        
        418
        #           802.11ac WLAN Adapter
        
        419
        # AX5Lst:   Bus 001 Device 015: ID a69c:5721 aicsemi Aic MSC
        
        420
        # AX5L:     Bus 001 Device 016: ID 368b:88df AICSemi AIC8800DC
        
        421
        # The manufacturer:product description is too bare. Just use our own.
        
        422
        lsusb_() {
        
        423
            local fname fdir usbid msg
        
        424
        
            
        425
            for fname in /sys/bus/usb/devices/*/idVendor; do
        
        426
                fdir=${fname%/*}
        
        427
                usbid="$(cat "$fname"):$(cat "$fdir/idProduct")"
        
        428
                # Return only our own devices
        
        429
                case "$usbid" in
        
        430
                0bda:8812) msg="Brostrend AC1Lv1/AC3Lv1 Wi-Fi adapter" ;;
        
        431
                0bda:b812) msg="Brostrend AC1L/AC3L Wi-Fi adapter" ;;
        
        432
                0bda:c811) msg="Brostrend AC5L Wi-Fi adapter" ;;
        
        433
                0bda:1a2b) msg="Brostrend AX1L/AX4L Wi-Fi adapter (storage mode)" ;;
        
        434
                0bda:b832) msg="Brostrend AX1L/AX4L Wi-Fi adapter" ;;
        
        435
                a69c:5721) msg="Brostrend AX5L Wi-Fi adapter (storage mode)" ;;
        
        436
                368b:88df) msg="Brostrend AX5L Wi-Fi adapter" ;;
        
        437
                *) continue ;;
        
        438
                esac
        
        439
                # TODO: try to detect if it's a USB2 or USB3 port
        
        440
                echo "$usbid $msg"
        
        441
            done
        
        442
        }
        
        443
        
            
        444
        pause_exit() {
        
        445
            local _dummy
        
        446
        
            
        447
            if [ "$_PAUSE_ON_EXIT" = 1 ]; then
        
        448
                bold -n "Press [Enter] to close the current window."
        
        449
                read -r _dummy
        
        450
            fi
        
        451
            exit "${1:-0}"
        
        452
        }
        
        453
        
            
        454
        re() {
        
        455
            "$@" || request_info "Aborting, command failed: $*"
        
        456
        }
        
        457
        
            
        458
        request_info() {
        
        459
            if [ -n "$1" ]; then
        
        460
                echo "$1" >&2
        
        461
                shift
        
        462
            fi
        
        463
            troubleshoot >/tmp/troubleshooting.txt 2>&1
        
        464
            if [ $# -gt 0 ]; then
        
        465
                rt "$@" >>/tmp/troubleshooting.txt
        
        466
            fi
        
        467
            die "
        
        468
        ===================================================
        
        469
         ERROR: The driver was NOT successfully installed!
        
        470
        ===================================================
        
        471
        1) Please select ALL the text in this terminal, then right click with the
        
        472
           mouse and select Copy, and finally paste all the text in an email to:
        
        473
           support@brostrend.com
        
        474
        2) Please also attach this autogenerated log file to the email:
        
        475
           /tmp/troubleshooting.txt
        
        476
           If you want to view it, run:
        
        477
           xdg-open /tmp/troubleshooting.txt
        
        478
        3) Some common issues are documented in:
        
        479
           https://linux.brostrend.com/troubleshooting/"
        
        480
        }
        
        481
        
            
        482
        rw() {
        
        483
            "$@" || echo "Warning, command failed: $*" >&2
        
        484
        }
        
        485
        
            
        486
        # Echo and run a troubleshooting command, and log its output
        
        487
        rt() {
        
        488
            local fflag iflag eflag
        
        489
        
            
        490
            while [ -n "$1" ]; do
        
        491
                case "$1" in
        
        492
                -f) fflag=1 ;;
        
        493
                -i) iflag=1 ;;
        
        494
                -e) eflag=1 ;;
        
        495
                *) break ;;
        
        496
                esac
        
        497
                shift
        
        498
            done
        
        499
            # Check if the binary doesn't exist, e.g. apt on Fedora
        
        500
            if [ "$fflag" = 1 ]; then
        
        501
                # And either return failure,
        
        502
                is_command "$1" || return 1
        
        503
            elif [ "$iflag" = 1 ]; then
        
        504
                # ...or ignore it and return success
        
        505
                is_command "$1" || return 0
        
        506
            fi
        
        507
            printf "\n# %s\n" "$*"
        
        508
            if [ "$eflag" = 1 ]; then
        
        509
                # Use eval, e.g. for `command 1 | command 2`
        
        510
                eval "$*" || return $?
        
        511
            else
        
        512
                "$@" || return $?
        
        513
            fi
        
        514
        }
        
        515
        
            
        516
        troubleshoot() {
        
        517
            echo "Troubleshooting information collected on $(date)"
        
        518
            rt uname -a
        
        519
            rt grep PRETTY /etc/os-release
        
        520
            rt -i dpkg --print-architecture
        
        521
            rt lsusb_
        
        522
            rt -f -e lsmod "| grep -wE '88...u|aic8800.*'" ||
        
        523
                rt -e ls "/sys/module/ | grep -wE '88...u|aic8800.*'"
        
        524
            rt -i -e rfkill list
        
        525
            rt -i -e mokutil --sb-state
        
        526
            rt -f dkms status || rt -i apt policy dkms
        
        527
            rt -i -e dpkg "-l '*-dkms' | grep ^ii"
        
        528
            rt ip a
        
        529
            rt ls -d /lib/modules/*/build /usr/src/linux-headers-*
        
        530
            rt -f dpkg -S /boot /lib/modules /usr/src/ ||
        
        531
                rt -i rpm -qf /boot/vmlinu* /lib/modules/* /usr/src/*
        
        532
            # iw isn't available in vanilla Ubuntu GNOME 22.04, but iwlist is
        
        533
            rt -i iw reg get
        
        534
            rt -f nmcli dev wifi || rt -i iwlist scanning
        
        535
            # Try the faster variant, fallback to the safer ones
        
        536
            rt -f journalctl -b -n 5000 --file /[vr][au][rn]/log/journal/"$(cat /etc/machine-id)"/system.journal ||
        
        537
                rt -f journalctl -b -n 5000 ||
        
        538
                rt "dmesg | tail -n 5000"
        
        539
        }
        
        540
        
            
        541
        warn() {
        
        542
            bold "$@" >&2
        
        543
        }
        
        544
        
            
        545
        main() {
        
        546
            local title scriptpath
        
        547
        
            
        548
            case "$1" in
        
        549
            "") ;;
        
        550
            -p) _PAUSE_ON_EXIT=1 ;;
        
        551
            -t) _TROUBLESHOOT=1 ;;
        
        552
            *)
        
        553
                usage
        
        554
                exit 0
        
        555
                ;;
        
        556
            esac
        
        557
        
            
        558
            # First check if we need to spawn an x-terminal-emulator.
        
        559
            # Note that after pkexec we don't have access to $DISPLAY.
        
        560
            if [ "$_PAUSE_ON_EXIT" != 1 ] && { [ ! -t 0 ] || [ ! -t 1 ]; } &&
        
        561
                xmodmap -n >/dev/null 2>&1; then
        
        562
                title=${1##*/}
        
        563
                case "$title" in
        
        564
                -s | --source) title=${2##*/} ;;
        
        565
                '') title=${0##*/} ;;
        
        566
                esac
        
        567
                _PAUSE_ON_EXIT=1 exec x-terminal-emulator -T "$title" -e sh "$0" "$@"
        
        568
            fi
        
        569
        
            
        570
            # Get root access if we don't already have it
        
        571
            if [ "$(id -u)" -ne 0 ]; then
        
        572
                # Make the installer executable, in case it was downloaded from the web.
        
        573
                scriptpath="$(
        
        574
                    cd "$(dirname "$0")"
        
        575
                    pwd -P
        
        576
                )/$(basename "$0")"
        
        577
                test -x "$scriptpath" || chmod +x "$scriptpath"
        
        578
                test -x "$scriptpath" || die "Could not make $scriptpath executable"
        
        579
        
            
        580
                bold "Root access is required"
        
        581
                # Prefer sudo when available, to avoid pkexec-over-ssh issues:
        
        582
                # https://gitlab.freedesktop.org/polkit/polkit/-/issues/17
        
        583
                if groups | grep -qwE 'sudo|wheel' && is_command sudo; then
        
        584
                    exec sudo "$scriptpath" ${_PAUSE_ON_EXIT:+-p} "$@"
        
        585
                else
        
        586
                    # TODO: for some reason, a delay is needed here, otherwise pkexec might not appear!
        
        587
                    sleep 1
        
        588
                    exec pkexec "$scriptpath" ${_PAUSE_ON_EXIT:+-p} "$@"
        
        589
                fi
        
        590
            fi
        
        591
        
            
        592
            # Tolerate users using `su` instead of `su -`
        
        593
            if ! echo "$PATH" | grep -qw sbin; then
        
        594
                export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        
        595
            fi
        
        596
            busybox_fallbacks
        
        597
            if [ "$_TROUBLESHOOT" = "1" ]; then
        
        598
                troubleshoot >/tmp/troubleshooting.txt 2>&1
        
        599
                die "The troubleshooting information was saved in this file:
        
        600
            /tmp/troubleshooting.txt
        
        601
        If you want to view it, run:
        
        602
            xdg-open /tmp/troubleshooting.txt
        
        603
        Please attach that file in an email to:
        
        604
            support@brostrend.com"
        
        605
            fi
        
        606
            select_driver
        
        607
            detect_package_manager
        
        608
            install_prerequisites
        
        609
            install_driver
        
        610
            bold "
        
        611
        =====================================================
        
        612
         The driver was successfully installed!
        
        613
         We'd appreciate an Amazon product review:
        
        614
         https://www.amazon.com/review/create-review/listing
        
        615
        ====================================================="
        
        616
            pause_exit
        
        617
        }
        
        618
        
            
        619
        main "$@"