From 2c8b858075958d14e1367d3ef4cdf8194339b12f Mon Sep 17 00:00:00 2001 From: arlophoenix Date: Mon, 3 Aug 2026 12:00:06 +1200 Subject: [PATCH] Gate the camera package check on the model, and migrate the dead feed host ensure_mjpg_streamer_packages tested /usr/bin/mjpg_streamer with no $model check, but only the K1 2025 camera services read /usr/bin and /usr/lib; the K1, 3V3, 3KE, 10SE and E5M services read /opt/bin and /opt/lib, which is Entware's territory. Split the function so each model is checked against the path its own service actually uses, and move the check ahead of the steps that disable the running streamer and copy the init script, so a failure leaves the printer as it was and hands control back to the menu instead of terminating helper.sh through the global set -e. Removing that path also removed both seds that rewrote /opt/etc/opkg.conf, and those seds were the only thing repairing printers still pointed at bin.tranducanh.com after that host stopped serving the repository. Replace them with a deliberate one-shot migration at startup that matches on the hostname so user-added feed lines survive, writes through a temp file so a full /opt image cannot truncate the config, and tells the user to run opkg update afterwards. Also stop install_entware reporting success unconditionally: it ran under set +e, symlinked /opt/libexec/sftp-server whether or not the install produced it, and printed a green checkmark either way. It also called prepare_opt, which was removed in 7a6ebfa and no longer exists. --- helper.sh | 3 ++ scripts/entware.sh | 71 ++++++++++++++++++++++++++++++++++++++++--- scripts/usb_camera.sh | 53 +++++++++++++++++--------------- 3 files changed, 98 insertions(+), 29 deletions(-) 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