487 lines
16 KiB
Bash
Executable File
487 lines
16 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
SOCK="${CUPS_SERVER_SOCK:-/var/run/cups/cups.sock}"
|
|
CUPS_RUNTIME_DEBUG_TO_KMSG="${CUPS_RUNTIME_DEBUG_TO_KMSG:-0}"
|
|
|
|
log() {
|
|
msg="$*"
|
|
echo "$msg" >> /log/cups.log
|
|
if [ "$CUPS_RUNTIME_DEBUG_TO_KMSG" = "1" ]; then
|
|
echo "DEBUG: CUPS bootstrap: $msg" > /dev/kmsg 2>/dev/null || true
|
|
fi
|
|
}
|
|
|
|
debug_echo() {
|
|
log "$*"
|
|
}
|
|
|
|
is_mounted() {
|
|
mnt="$1"
|
|
awk -v m="$mnt" '$2==m{found=1} END{exit found?0:1}' /proc/mounts
|
|
}
|
|
|
|
mount_nix_from_sd() {
|
|
mkdir -p /nix
|
|
if is_mounted /nix; then
|
|
return 0
|
|
fi
|
|
tries=10
|
|
while [ "$tries" -gt 0 ] && [ ! -b /dev/mmcblk0p2 ]; do
|
|
sleep 1
|
|
tries=$((tries - 1))
|
|
done
|
|
if [ ! -b /dev/mmcblk0p2 ]; then
|
|
echo "cups-runtime-bootstrap: /dev/mmcblk0p2 not found" >&2
|
|
return 1
|
|
fi
|
|
mount -t ext4 /dev/mmcblk0p2 /nix >> /log/cups.log 2>&1
|
|
}
|
|
|
|
if [ -f /cups-runtime.env ]; then
|
|
# shellcheck source=/dev/null
|
|
. /cups-runtime.env
|
|
CUPS_RUNTIME_DEBUG_TO_KMSG="${CUPS_RUNTIME_DEBUG_TO_KMSG:-0}"
|
|
fi
|
|
|
|
BRLASER_DROPIN_ROOT=""
|
|
mkdir -p /mnt/boot /var/cups-extra
|
|
BRLASER_RUNTIME_ROOT=/var/cups-extra/brlaser-runtime
|
|
mkdir -p "$BRLASER_RUNTIME_ROOT/filter" "$BRLASER_RUNTIME_ROOT/lib"
|
|
SHOULD_LOAD_DROPIN=0
|
|
case "${CUPS_RUNTIME_LOAD_DROPIN:-auto}" in
|
|
1|yes|true|on)
|
|
SHOULD_LOAD_DROPIN=1
|
|
;;
|
|
0|no|false|off)
|
|
SHOULD_LOAD_DROPIN=0
|
|
;;
|
|
*)
|
|
[ -z "${BRLASER_ROOT:-}" ] && SHOULD_LOAD_DROPIN=1
|
|
;;
|
|
esac
|
|
if [ "$SHOULD_LOAD_DROPIN" -eq 1 ] && [ -b /dev/mmcblk0p1 ]; then
|
|
mount -t vfat /dev/mmcblk0p1 /mnt/boot >/dev/null 2>&1 || true
|
|
for cand in /mnt/boot/brlaser-root.tar.gz /mnt/boot/brlaser-root.tgz /mnt/boot/brlaser-root.tar; do
|
|
if [ -f "$cand" ]; then
|
|
rm -rf /var/cups-extra/brlaser-root
|
|
mkdir -p /var/cups-extra/brlaser-root
|
|
if tar -xf "$cand" -C /var/cups-extra/brlaser-root >/dev/null 2>&1; then
|
|
BRLASER_DROPIN_ROOT=/var/cups-extra/brlaser-root
|
|
if [ -d /var/cups-extra/brlaser-root/brlaser-root ]; then
|
|
BRLASER_DROPIN_ROOT=/var/cups-extra/brlaser-root/brlaser-root
|
|
fi
|
|
debug_echo "loaded brlaser drop-in from $(basename "$cand")"
|
|
else
|
|
debug_echo "failed to extract brlaser drop-in $(basename "$cand")"
|
|
fi
|
|
break
|
|
fi
|
|
done
|
|
umount /mnt/boot >/dev/null 2>&1 || true
|
|
elif [ "$SHOULD_LOAD_DROPIN" -eq 0 ]; then
|
|
debug_echo "drop-in loading disabled"
|
|
else
|
|
debug_echo "no boot partition for drop-in loading"
|
|
fi
|
|
|
|
# Minimal identity DB expected by cupsd in initramfs.
|
|
if [ ! -f /etc/group ]; then
|
|
cat > /etc/group <<'EOF_GROUP'
|
|
root:x:0:
|
|
sys:x:3:
|
|
lp:x:7:
|
|
lpadmin:x:19:
|
|
EOF_GROUP
|
|
fi
|
|
if [ ! -f /etc/passwd ]; then
|
|
cat > /etc/passwd <<'EOF_PASSWD'
|
|
root:x:0:0:root:/root:/bin/sh
|
|
lp:x:7:7:CUPS:/var/spool/cups:/bin/false
|
|
EOF_PASSWD
|
|
fi
|
|
grep -q '^lpadmin:' /etc/group || echo 'lpadmin:x:19:' >> /etc/group
|
|
grep -q '^lp:' /etc/group || echo 'lp:x:7:' >> /etc/group
|
|
grep -q '^sys:' /etc/group || echo 'sys:x:3:' >> /etc/group
|
|
grep -q '^root:' /etc/group || echo 'root:x:0:' >> /etc/group
|
|
grep -q '^lp:' /etc/passwd || echo 'lp:x:7:7:CUPS:/var/spool/cups:/bin/false' >> /etc/passwd
|
|
|
|
mkdir -p /etc/cups /var/cache/cups /var/spool/cups/tmp /run/cups /var/run/cups /var/log/cups
|
|
chmod 1777 /var/spool/cups/tmp
|
|
|
|
mount_nix_from_sd
|
|
|
|
CUPS_BIN_ROOT="$(readlink /bin/cupsd 2>/dev/null | sed 's#/bin/cupsd$##')"
|
|
[ -z "$CUPS_BIN_ROOT" ] && CUPS_BIN_ROOT="/nix/store"
|
|
CUPS_DATA_ROOT="$CUPS_BIN_ROOT"
|
|
if [ ! -d "${CUPS_DATA_ROOT}/share/cups" ] && [ -d "${CUPS_BIN_ROOT}-lib/share/cups" ]; then
|
|
CUPS_DATA_ROOT="${CUPS_BIN_ROOT}-lib"
|
|
fi
|
|
|
|
repair_elf_runtime() {
|
|
elf_bin="$1"
|
|
[ -x "$elf_bin" ] || return 0
|
|
[ -x /bin/readelf ] || return 0
|
|
|
|
interp_path="$(/bin/readelf -l "$elf_bin" 2>/dev/null | sed -n 's@.*Requesting program interpreter: \(.*\)]@\1@p' | head -n 1)"
|
|
if [ -n "$interp_path" ] && [ ! -e "$interp_path" ] && [ -e /lib/ld-musl-armhf.so.1 ]; then
|
|
mkdir -p "$(dirname "$interp_path")"
|
|
ln -snf /lib/ld-musl-armhf.so.1 "$interp_path" 2>/dev/null || true
|
|
debug_echo "repaired interp for $(basename "$elf_bin") -> $interp_path"
|
|
fi
|
|
|
|
runpaths="$(/bin/readelf -d "$elf_bin" 2>/dev/null | sed -n 's@.*Library runpath: \[\(.*\)\]@\1@p' | head -n 1)"
|
|
[ -n "$runpaths" ] || return 0
|
|
|
|
gcc_lib_path="$(find /nix/store -path '*gcc*lib*/armv6l-unknown-linux-musleabihf/lib' 2>/dev/null | head -n 1)"
|
|
cups_lib_path=""
|
|
if [ -d "${CUPS_BIN_ROOT}/lib" ]; then
|
|
cups_lib_path="${CUPS_BIN_ROOT}/lib"
|
|
elif [ -d "${CUPS_BIN_ROOT}-lib/lib" ]; then
|
|
cups_lib_path="${CUPS_BIN_ROOT}-lib/lib"
|
|
fi
|
|
|
|
oldifs="$IFS"
|
|
IFS=':'
|
|
for rp in $runpaths; do
|
|
[ -n "$rp" ] || continue
|
|
[ -e "$rp" ] && continue
|
|
target=""
|
|
case "$rp" in
|
|
*musl*"/lib") target="/lib" ;;
|
|
*cups*"/lib") target="$cups_lib_path" ;;
|
|
*gcc*"/armv6l-unknown-linux-musleabihf/lib") target="$gcc_lib_path" ;;
|
|
esac
|
|
if [ -n "$target" ] && [ -d "$target" ]; then
|
|
mkdir -p "$(dirname "$rp")"
|
|
rm -rf "$rp" 2>/dev/null || true
|
|
ln -snf "$target" "$rp" 2>/dev/null || true
|
|
debug_echo "repaired runpath for $(basename "$elf_bin") -> $rp"
|
|
fi
|
|
done
|
|
IFS="$oldifs"
|
|
}
|
|
|
|
install_brlaser_wrapper() {
|
|
filter_bin="/var/cups-serverbin/lib/cups/filter/rastertobrlaser"
|
|
runtime_filter="$BRLASER_RUNTIME_ROOT/filter/rastertobrlaser.real"
|
|
[ -x "$filter_bin" ] || return 0
|
|
|
|
cp -a "$filter_bin" "$runtime_filter" 2>/dev/null || return 0
|
|
|
|
cat > "$filter_bin" <<'EOF_WRAP'
|
|
#!/bin/sh
|
|
RUNTIME_ROOT="/var/cups-extra/brlaser-runtime"
|
|
REAL_FILTER="$RUNTIME_ROOT/filter/rastertobrlaser.real"
|
|
[ -x "$REAL_FILTER" ] || exit 127
|
|
LD_PATHS="$RUNTIME_ROOT/lib:/lib:/usr/lib"
|
|
if [ -n "${BRLASER_LD_LIBRARY_PATH:-}" ]; then
|
|
LD_PATHS="$BRLASER_LD_LIBRARY_PATH:$LD_PATHS"
|
|
fi
|
|
if [ -n "${LD_LIBRARY_PATH:-}" ]; then
|
|
LD_PATHS="$LD_LIBRARY_PATH:$LD_PATHS"
|
|
fi
|
|
export LD_LIBRARY_PATH="$LD_PATHS"
|
|
exec "$REAL_FILTER" "$@"
|
|
EOF_WRAP
|
|
chmod 555 "$filter_bin" 2>/dev/null || true
|
|
debug_echo "installed brlaser wrapper at $filter_bin"
|
|
}
|
|
|
|
# Copy CUPS serverbin to writable storage.
|
|
mkdir -p /var/cups-serverbin/lib
|
|
rm -rf /var/cups-serverbin/lib/cups
|
|
if [ -d "${CUPS_BIN_ROOT}/lib/cups" ]; then
|
|
cp -a "${CUPS_BIN_ROOT}/lib/cups" /var/cups-serverbin/lib/
|
|
fi
|
|
for extra_root in "$BRLASER_DROPIN_ROOT" "${BRLASER_ROOT:-}" "${CUPS_FILTERS_ROOT:-}"; do
|
|
[ -n "$extra_root" ] || continue
|
|
if [ -d "$extra_root/lib/cups" ]; then
|
|
cp -a "$extra_root/lib/cups/." /var/cups-serverbin/lib/cups/ 2>/dev/null || true
|
|
fi
|
|
if [ -d "$extra_root/lib" ]; then
|
|
find "$extra_root/lib" -maxdepth 2 -type f \( -name '*.so' -o -name '*.so.*' \) -exec cp -a {} "$BRLASER_RUNTIME_ROOT/lib/" \; 2>/dev/null || true
|
|
fi
|
|
done
|
|
if [ -d /var/cups-serverbin/lib/cups ]; then
|
|
chown root:root /var/cups-serverbin/lib/cups 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/backend 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/filter 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/driver 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/daemon 2>/dev/null || true
|
|
chmod 755 /var/cups-serverbin/lib/cups 2>/dev/null || true
|
|
chmod 755 /var/cups-serverbin/lib/cups/backend 2>/dev/null || true
|
|
chmod 755 /var/cups-serverbin/lib/cups/filter 2>/dev/null || true
|
|
chmod 755 /var/cups-serverbin/lib/cups/driver 2>/dev/null || true
|
|
chmod 755 /var/cups-serverbin/lib/cups/daemon 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/backend/* 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/filter/* 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/driver/* 2>/dev/null || true
|
|
chown root:root /var/cups-serverbin/lib/cups/daemon/* 2>/dev/null || true
|
|
chmod 555 /var/cups-serverbin/lib/cups/backend/* 2>/dev/null || true
|
|
chmod 555 /var/cups-serverbin/lib/cups/filter/* 2>/dev/null || true
|
|
chmod 555 /var/cups-serverbin/lib/cups/driver/* 2>/dev/null || true
|
|
chmod 555 /var/cups-serverbin/lib/cups/daemon/* 2>/dev/null || true
|
|
fi
|
|
if [ -d /var/cups-serverbin/lib/cups/backend ]; then
|
|
chmod 700 /var/cups-serverbin/lib/cups/backend/* 2>/dev/null || true
|
|
fi
|
|
|
|
# Build writable CUPS data dir and merge optional models/PPDs.
|
|
CUPS_RUNTIME_DATA=/var/cups-data
|
|
rm -rf "$CUPS_RUNTIME_DATA"
|
|
mkdir -p "$CUPS_RUNTIME_DATA"
|
|
if [ -d "${CUPS_DATA_ROOT}/share/cups" ]; then
|
|
if [ "${CUPS_RUNTIME_DATA_COPY:-minimal}" = "full" ]; then
|
|
cp -a "${CUPS_DATA_ROOT}/share/cups/." "$CUPS_RUNTIME_DATA/" 2>/dev/null || true
|
|
else
|
|
for d in mime usb drv ppdc; do
|
|
if [ -d "${CUPS_DATA_ROOT}/share/cups/$d" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/$d"
|
|
cp -a "${CUPS_DATA_ROOT}/share/cups/$d/." "$CUPS_RUNTIME_DATA/$d/" 2>/dev/null || true
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
for extra_root in "$BRLASER_DROPIN_ROOT" "${BRLASER_ROOT:-}" "${CUPS_FILTERS_ROOT:-}"; do
|
|
[ -n "$extra_root" ] || continue
|
|
if [ -d "$extra_root/share/cups/drv" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/drv"
|
|
cp -a "$extra_root/share/cups/drv/." "$CUPS_RUNTIME_DATA/drv/" 2>/dev/null || true
|
|
fi
|
|
if [ -d "$extra_root/share/cups/model" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/model"
|
|
cp -a "$extra_root/share/cups/model/." "$CUPS_RUNTIME_DATA/model/" 2>/dev/null || true
|
|
fi
|
|
if [ -d "$extra_root/share/cups/ppdc" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/ppdc"
|
|
cp -a "$extra_root/share/cups/ppdc/." "$CUPS_RUNTIME_DATA/ppdc/" 2>/dev/null || true
|
|
fi
|
|
if [ -d "$extra_root/share/ppd" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/model"
|
|
cp -a "$extra_root/share/ppd/." "$CUPS_RUNTIME_DATA/model/" 2>/dev/null || true
|
|
fi
|
|
done
|
|
mkdir -p "$CUPS_RUNTIME_DATA/model" "$CUPS_RUNTIME_DATA/drv" "$CUPS_RUNTIME_DATA/usb" "$CUPS_RUNTIME_DATA/mime" "$CUPS_RUNTIME_DATA/ppdc"
|
|
chown root:root "$CUPS_RUNTIME_DATA" "$CUPS_RUNTIME_DATA/model" "$CUPS_RUNTIME_DATA/drv" "$CUPS_RUNTIME_DATA/usb" "$CUPS_RUNTIME_DATA/mime" "$CUPS_RUNTIME_DATA/ppdc" 2>/dev/null || true
|
|
chmod 755 "$CUPS_RUNTIME_DATA" "$CUPS_RUNTIME_DATA/model" "$CUPS_RUNTIME_DATA/drv" "$CUPS_RUNTIME_DATA/usb" "$CUPS_RUNTIME_DATA/mime" "$CUPS_RUNTIME_DATA/ppdc" 2>/dev/null || true
|
|
|
|
if [ "${CUPS_RUNTIME_REPAIR_ALL_FILTERS:-0}" = "1" ] && [ -d /var/cups-serverbin/lib/cups/filter ]; then
|
|
for f in /var/cups-serverbin/lib/cups/filter/*; do
|
|
[ -f "$f" ] || continue
|
|
repair_elf_runtime "$f"
|
|
done
|
|
if [ -d /var/cups-serverbin/lib/cups/driver ]; then
|
|
for f in /var/cups-serverbin/lib/cups/driver/*; do
|
|
[ -f "$f" ] || continue
|
|
repair_elf_runtime "$f"
|
|
done
|
|
fi
|
|
else
|
|
repair_elf_runtime /var/cups-serverbin/lib/cups/filter/rastertobrlaser
|
|
repair_elf_runtime /var/cups-serverbin/lib/cups/driver/drv
|
|
repair_elf_runtime /var/cups-serverbin/lib/cups/driver/cups-driverd
|
|
fi
|
|
install_brlaser_wrapper
|
|
|
|
run_ppdc_brlaser() {
|
|
out_dir="$1"
|
|
drv_file="$2"
|
|
timeout_secs="${3:-10}"
|
|
[ -n "$out_dir" ] && [ -n "$drv_file" ] || return 1
|
|
|
|
set -- /bin/ppdc -d "$out_dir"
|
|
for inc in "$CUPS_RUNTIME_DATA/ppdc" "$CUPS_RUNTIME_DATA/drv" "$CUPS_DATA_ROOT/share/cups/ppdc"; do
|
|
[ -d "$inc" ] || continue
|
|
set -- "$@" -I "$inc"
|
|
done
|
|
set -- "$@" "$drv_file"
|
|
/bin/timeout "$timeout_secs" "$@"
|
|
}
|
|
|
|
BRLASER_DRV="$CUPS_RUNTIME_DATA/drv/brlaser.drv"
|
|
if [ "${CUPS_RUNTIME_ENABLE_PPDC:-0}" = "1" ] && [ -f "$BRLASER_DRV" ] && [ -x /bin/ppdc ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/model"
|
|
run_ppdc_brlaser "$CUPS_RUNTIME_DATA/model" "$BRLASER_DRV" 10 >/dev/null 2>&1 || debug_echo "ppdc model generation timed out/failed"
|
|
fi
|
|
|
|
cat > /etc/cups/cups-files.conf <<EOF_CFG
|
|
SystemGroup root lpadmin
|
|
FileDevice Yes
|
|
RequestRoot /var/spool/cups
|
|
ServerRoot /etc/cups
|
|
CacheDir /var/cache/cups
|
|
DataDir ${CUPS_RUNTIME_DATA}
|
|
ServerBin /var/cups-serverbin/lib/cups
|
|
EOF_CFG
|
|
|
|
if [ ! -f /etc/cups/cupsd.conf ]; then
|
|
cat > /etc/cups/cupsd.conf <<'EOF_CUPSD'
|
|
LogLevel warn
|
|
Listen 0.0.0.0:631
|
|
Browsing Off
|
|
DefaultAuthType None
|
|
WebInterface No
|
|
<Location />
|
|
Order allow,deny
|
|
Allow all
|
|
</Location>
|
|
EOF_CUPSD
|
|
fi
|
|
|
|
BRLASER_BLOCK_REASON=""
|
|
brlaser_filter_usable() {
|
|
filter_bin="/var/cups-serverbin/lib/cups/filter/rastertobrlaser"
|
|
BRLASER_BLOCK_REASON=""
|
|
[ -x "$filter_bin" ] || { BRLASER_BLOCK_REASON="filter missing/not executable"; return 1; }
|
|
[ -x /bin/readelf ] || { BRLASER_BLOCK_REASON="readelf unavailable for probe"; return 1; }
|
|
|
|
interp_path="$(/bin/readelf -l "$filter_bin" 2>/dev/null | sed -n 's@.*Requesting program interpreter: \(.*\)]@\1@p' | head -n 1)"
|
|
if [ -n "$interp_path" ] && [ ! -e "$interp_path" ]; then
|
|
BRLASER_BLOCK_REASON="missing interpreter: $interp_path"
|
|
return 1
|
|
fi
|
|
|
|
runpaths="$(/bin/readelf -d "$filter_bin" 2>/dev/null | sed -n 's@.*Library runpath: \[\(.*\)\]@\1@p' | head -n 1)"
|
|
needed_libs="$(/bin/readelf -d "$filter_bin" 2>/dev/null | sed -n 's@.*Shared library: \[\(.*\)\]@\1@p')"
|
|
search_paths="$runpaths:/lib:/usr/lib"
|
|
for lib in $needed_libs; do
|
|
found=""
|
|
for p in $(echo "$search_paths" | tr ':' '\n'); do
|
|
[ -n "$p" ] || continue
|
|
if [ -e "$p/$lib" ]; then
|
|
found=1
|
|
break
|
|
fi
|
|
done
|
|
if [ -z "$found" ]; then
|
|
BRLASER_BLOCK_REASON="missing shared lib: $lib"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
probe_err="/tmp/brlaser-probe.err"
|
|
: > "$probe_err"
|
|
/bin/timeout 2 "$filter_bin" >/dev/null 2>"$probe_err"
|
|
rc="$?"
|
|
if grep -q -E "Error loading shared library|Error relocating|not found" "$probe_err"; then
|
|
BRLASER_BLOCK_REASON="ABI mismatch (relocation/shared-lib errors)"
|
|
return 1
|
|
fi
|
|
if [ "$rc" -eq 126 ] || [ "$rc" -eq 127 ]; then
|
|
BRLASER_BLOCK_REASON="filter failed to execute (rc=$rc)"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
find_runtime_brlaser_ppd() {
|
|
model="$1"
|
|
model_dir="$CUPS_RUNTIME_DATA/model"
|
|
[ -d "$model_dir" ] || return 0
|
|
|
|
if [ -n "$model" ]; then
|
|
ppd="$(find "$model_dir" -type f \( -iname "*${model}*.ppd" -o -iname "*${model}*.ppd.gz" \) | head -n 1)"
|
|
[ -n "$ppd" ] && { echo "$ppd"; return 0; }
|
|
|
|
ppd="$(grep -RilsF "ModelName: \"Brother $model\"" "$model_dir" 2>/dev/null | head -n 1)"
|
|
[ -n "$ppd" ] && { echo "$ppd"; return 0; }
|
|
|
|
ppd="$(grep -RilsF "MDL:$model;" "$model_dir" 2>/dev/null | head -n 1)"
|
|
[ -n "$ppd" ] && { echo "$ppd"; return 0; }
|
|
fi
|
|
|
|
find "$model_dir" -type f \
|
|
\( -iname 'brl*.ppd' -o -iname 'brl*.ppd.gz' -o -iname '*Brother*HL-*.ppd' -o -iname '*Brother*HL-*.ppd.gz' \) \
|
|
| head -n 1
|
|
}
|
|
|
|
provision_hbp_queue() {
|
|
queue_uri="$1"
|
|
[ -n "$queue_uri" ] || return 1
|
|
|
|
if ! brlaser_filter_usable; then
|
|
debug_echo "HBP blocked: skipping test-hbp queue (${BRLASER_BLOCK_REASON})"
|
|
return 0
|
|
fi
|
|
|
|
ppd=""
|
|
model_name="$(printf '%s' "$queue_uri" | sed -n 's@^usb://Brother/\([^?]*\).*$@\1@p' | sed 's/%20/ /g')"
|
|
if [ -d "$CUPS_RUNTIME_DATA/model" ]; then
|
|
ppd="$(find_runtime_brlaser_ppd "$model_name")"
|
|
fi
|
|
if [ -z "$ppd" ] && [ -x /bin/ppdc ] && [ -f "$CUPS_RUNTIME_DATA/drv/brlaser.drv" ]; then
|
|
mkdir -p "$CUPS_RUNTIME_DATA/model"
|
|
run_ppdc_brlaser "$CUPS_RUNTIME_DATA/model" "$CUPS_RUNTIME_DATA/drv/brlaser.drv" 10 >/dev/null 2>&1 || true
|
|
ppd="$(find_runtime_brlaser_ppd "$model_name")"
|
|
fi
|
|
|
|
if [ -n "$ppd" ]; then
|
|
/bin/lpadmin -h "$SOCK" -x test-hbp >/dev/null 2>&1 || true
|
|
/bin/lpadmin -h "$SOCK" -p test-hbp -E -v "$queue_uri" -P "$ppd" >> /log/cups.log 2>&1 || true
|
|
debug_echo "queue test-hbp configured ppd=$ppd"
|
|
else
|
|
debug_echo "no brlaser PPD found for non-raw queue"
|
|
fi
|
|
}
|
|
|
|
maybe_provision_hbp_async() {
|
|
queue_uri="$1"
|
|
[ -n "$queue_uri" ] || return 0
|
|
if [ "${CUPS_RUNTIME_HBP_ASYNC:-1}" = "1" ]; then
|
|
(
|
|
provision_hbp_queue "$queue_uri"
|
|
) &
|
|
debug_echo "scheduling test-hbp provisioning in background"
|
|
else
|
|
provision_hbp_queue "$queue_uri"
|
|
fi
|
|
}
|
|
|
|
provision_runtime_queue() {
|
|
[ -x /bin/lpadmin ] || return 1
|
|
[ -S "$SOCK" ] || return 1
|
|
|
|
queue_uri=""
|
|
usb_backend="/var/cups-serverbin/lib/cups/backend/usb"
|
|
if [ -x "$usb_backend" ]; then
|
|
queue_uri="$($usb_backend 2>/dev/null | awk '$1=="direct" && $2 ~ /^usb:\/\// {print $2; exit}')"
|
|
fi
|
|
if [ -z "$queue_uri" ] && [ -c /dev/usb/lp0 ]; then
|
|
queue_uri="file:///dev/usb/lp0"
|
|
fi
|
|
[ -n "$queue_uri" ] || return 1
|
|
|
|
/bin/lpadmin -h "$SOCK" -x test >/dev/null 2>&1 || true
|
|
/bin/lpadmin -h "$SOCK" -p test -E -v "$queue_uri" -m raw >> /log/cups.log 2>&1 || return 1
|
|
debug_echo "queue test configured uri=$queue_uri (raw)"
|
|
maybe_provision_hbp_async "$queue_uri"
|
|
return 0
|
|
}
|
|
|
|
if /bin/cupsd >> /log/cups.log 2>&1; then
|
|
if ! provision_runtime_queue; then
|
|
if [ "${CUPS_RUNTIME_QUEUE_RETRY:-0}" = "1" ]; then
|
|
debug_echo "no printer URI discovered; starting retry loop"
|
|
(
|
|
retries=90
|
|
while [ "$retries" -gt 0 ]; do
|
|
sleep 2
|
|
if provision_runtime_queue; then
|
|
exit 0
|
|
fi
|
|
retries=$((retries - 1))
|
|
done
|
|
debug_echo "queue provisioning timed out (no URI discovered)"
|
|
) &
|
|
else
|
|
debug_echo "no printer URI discovered; retry loop disabled"
|
|
fi
|
|
fi
|
|
debug_echo "scheduler started"
|
|
else
|
|
debug_echo "failed to start cupsd"
|
|
fi
|
|
|
|
log "bootstrap complete"
|