diff --git a/helper.sh b/helper.sh index 702d0c8..08c5d5e 100755 --- a/helper.sh +++ b/helper.sh @@ -111,5 +111,8 @@ if [ -z "$model" ] && [ "$model" != "K1_2025" ] && [ ! -f $INITD_FOLDER/S58facto fi set_permissions +# Repairs an existing /opt/etc/opkg.conf still pointing at the retired feed +# host. Must not be able to fail the script -- this is the recovery tool. +migrate_entware_feed_host || true update_menu main_menu diff --git a/scripts/entware.sh b/scripts/entware.sh index 813623f..a8f00ec 100755 --- a/scripts/entware.sh +++ b/scripts/entware.sh @@ -64,6 +64,63 @@ function k1_2025_migrate_entware_boot_if_needed() { k1_2025_write_entware_init_script } +# The installer runs with errexit disabled, so nothing below it notices a +# failure. Check that it produced the two things the rest of the script depends +# on, and report the first problem found rather than claiming success. +function verify_entware_install(){ + if [ ! -f /opt/libexec/sftp-server ]; then + error_msg "Entware install did not complete: openssh-sftp-server is missing, SFTP will not work." + return 1 + fi + if [ ! -s /opt/etc/opkg.conf ]; then + error_msg "Entware install did not complete: /opt/etc/opkg.conf is missing or empty." + return 1 + fi + if ! grep -q '^src/gz ' /opt/etc/opkg.conf; then + error_msg "Entware install did not complete: /opt/etc/opkg.conf has no package feed." + return 1 + fi + return 0 +} + +# /opt/etc/opkg.conf lives on the printer's persistent /opt, which no helper +# script update touches, so printers set up before the feed moved still point at +# bin.tranducanh.com. That host stopped serving the repository. Repair it in +# place, matching on the hostname so any feed lines the user added survive. +function migrate_entware_feed_host(){ + local conf="/opt/etc/opkg.conf" + local tmp + + # On K1 2025 /opt is a loop mount that only S48entware creates; helper.sh + # never mounts it, so an unmounted /opt means there is nothing to migrate. + if [ "$model" = "K1_2025" ] && ! grep -q " /opt " /proc/mounts 2>/dev/null; then + return 0 + fi + [ -f "$conf" ] || return 0 + grep -q 'bin\.tranducanh\.com' "$conf" || return 0 + + # /opt is a fixed-size image and can be full. Build the replacement beside the + # original and only swap it in once it is known to be complete -- "sed -i" + # would leave a truncated or empty config behind. + tmp="${conf}.new.$$" + if ! sed 's|bin\.tranducanh\.com|bin.entware.net|g' "$conf" > "$tmp" \ + || [ ! -s "$tmp" ] \ + || [ "$(wc -l < "$tmp")" -ne "$(wc -l < "$conf")" ] \ + || ! mv "$tmp" "$conf"; then + rm -f "$tmp" + return 1 + fi + + echo -e "${white}" + echo -e " ${green}Entware package feed moved to bin.entware.net (bin.tranducanh.com is gone).${white}" + echo -e " Run ${yellow}opkg update${white} before installing packages, so the package list is refreshed too." + echo + # main_menu clears the screen, so pause once to let the notice be read. Never + # let the prompt itself decide the outcome of a migration that succeeded. + read -p " Press Enter to continue... " _ || true + return 0 +} + function install_entware(){ entware_message local yn @@ -78,20 +135,24 @@ function install_entware(){ k1_2025_opt_mount $HS_FILES/fixes/curl -L "https://bin.entware.net/mipselsf-k3.4/installer/generic.sh" | sh export PATH=/opt/bin:/opt/sbin:$PATH - # I'm not sure why we were using Tranducanh.com. It got wiped and it broke everything. It makes more sense to just use the official one. - sed -i '1s|.*|src/gz entware http://bin.entware.net/mipselsf-k3.4|' /opt/etc/opkg.conf opkg update opkg install openssh-sftp-server - # Symlink also created on boot by S48entware - ln -sf /opt/libexec/sftp-server /usr/libexec/sftp-server + # Same guard as the S48entware boot script, which also creates this + # symlink: never point it at a file the install failed to produce. + mkdir -p /usr/libexec + if [ ! -e /usr/libexec/sftp-server ] && [ -f /opt/libexec/sftp-server ]; then + ln -sf /opt/libexec/sftp-server /usr/libexec/sftp-server + fi else - prepare_opt chmod 755 "$ENTWARE_URL" sh "$ENTWARE_URL" fi set -e + if ! verify_entware_install; then + return 0 + fi ok_msg "Entware has been installed successfully!" echo -e " Disconnect and reconnect SSH session, and you can now install packages with: ${yellow}opkg install ${white}" return;; diff --git a/scripts/usb_camera.sh b/scripts/usb_camera.sh index 2d23a66..473b74e 100755 --- a/scripts/usb_camera.sh +++ b/scripts/usb_camera.sh @@ -77,24 +77,24 @@ aspect_ratio: 16:9 EOF } +# Makes mjpg-streamer available for the camera service this model actually runs. +# Returns non-zero (after reporting) when it cannot; callers must check. function ensure_mjpg_streamer_packages(){ - # K-series firmware already ships mjpg-streamer at /usr/bin (I tested this on my K1 Max and someone on discord checked on the K1C) - [ -x /usr/bin/mjpg_streamer ] && return - - if "$ENTWARE_FILE" list | grep -q '^mjpg-streamer '; then - return - fi - if [ "$model" = "K1_2025" ]; then - echo -e "Info: Updating Entware repository for mjpg-streamer packages..." - sed -i '1s|.*|src/gz entware http://bin.entware.net/mipselsf-k3.4|' /opt/etc/opkg.conf - "$ENTWARE_FILE" update - fi - - if ! "$ENTWARE_FILE" list | grep -q '^mjpg-streamer '; then - error_msg "mjpg-streamer packages are not available in the configured Entware repository!" + # The 2025 camera services hardcode /usr/bin/mjpg_streamer and + # /usr/lib/mjpg-streamer, which the firmware supplies on a read-only + # squashfs. opkg writes to /opt and cannot help here. + [ -x /usr/bin/mjpg_streamer ] && return 0 + error_msg "mjpg_streamer not found in firmware; this model requires it." return 1 fi + + # Legacy K1/3V3/3KE/10SE/E5M: the services read /opt/bin and /opt/lib, so + # Entware is the source and the package list must be current. + echo -e "Info: Updating Entware repository for mjpg-streamer packages..." + "$ENTWARE_FILE" update || { error_msg "Could not refresh the package list."; return 1; } + "$ENTWARE_FILE" install mjpg-streamer mjpg-streamer-input-http \ + mjpg-streamer-input-uvc mjpg-streamer-output-http mjpg-streamer-www } function disable_entware_builtin_mjpg_streamer(){ @@ -130,6 +130,14 @@ function install_usb_camera(){ case "${yn}" in Y|y) echo -e "${white}" + # Check packages before anything destructive: a failure here must leave + # the printer exactly as it was, and must return to the menu rather + # than propagate through helper.sh's global "set -e". + echo -e "Info: Checking necessary packages..." + if ! ensure_mjpg_streamer_packages; then + error_msg "USB Camera Support has not been installed!" + return 0 + fi if [ "$model" = "K1_2025" ]; then k1_2025_migrate_entware_boot_if_needed disable_entware_builtin_mjpg_streamer @@ -175,11 +183,6 @@ function install_usb_camera(){ done fi chmod 755 "$USB_CAMERA_FILE" - echo -e "Info: Installing necessary packages..." - if [ ! -x /usr/bin/mjpg_streamer ]; then - ensure_mjpg_streamer_packages - "$ENTWARE_FILE" update && "$ENTWARE_FILE" install mjpg-streamer mjpg-streamer-input-http mjpg-streamer-input-uvc mjpg-streamer-output-http mjpg-streamer-www - fi if [ "$model" = "K1_2025" ]; then configure_usb_camera_k1_2025 if [ -f "$INITD_FOLDER"/S56moonraker_service ]; then @@ -212,6 +215,13 @@ function install_builtin_camera(){ case "${yn}" in Y|y) echo -e "${white}" + # Same ordering rule as install_usb_camera: nothing destructive runs + # until the packages are known to be in place. + echo -e "Info: Checking necessary packages..." + if ! ensure_mjpg_streamer_packages; then + error_msg "Built-in Camera Fix has not been installed!" + return 0 + fi k1_2025_migrate_entware_boot_if_needed disable_entware_builtin_mjpg_streamer echo -e "Info: Copying file..." @@ -221,11 +231,6 @@ function install_builtin_camera(){ rm -f "$BUILTIN_CAMERA_LEGACY_FILE" cp "$BUILTIN_CAMERA_K1_2025_URL" "$BUILTIN_CAMERA_FILE" chmod 755 "$BUILTIN_CAMERA_FILE" - echo -e "Info: Installing necessary packages..." - if [ ! -x /usr/bin/mjpg_streamer ]; then - ensure_mjpg_streamer_packages - "$ENTWARE_FILE" update && "$ENTWARE_FILE" install mjpg-streamer mjpg-streamer-input-http mjpg-streamer-input-uvc mjpg-streamer-output-http mjpg-streamer-www - fi configure_builtin_camera_k1_2025 if [ -f "$INITD_FOLDER"/S56moonraker_service ]; then stop_moonraker