Compare commits

..
15 Commits
Author SHA1 Message Date
KroeseandGitHub 51d6f3aeca fix: Reserve internal ports for user-mode forwarding (#1348) 2026-08-02 23:01:52 +02:00
KroeseandGitHub 4544620d48 feat: Increase indentation of printed QEMU arguments (#1347) 2026-08-01 05:49:50 +02:00
KroeseandGitHub de8468161f feat: Refactor negated command conditions (#1346) 2026-07-30 21:22:21 +02:00
renovate[bot]andGitHub 18d6be8210 chore(deps): update hadolint/hadolint-action action to v3.4.0 (#1345) 2026-07-30 21:06:27 +02:00
KroeseandGitHub e5b8cf3bf8 build: Update Passt to v2026_07_28 (#1344) 2026-07-30 10:10:41 +02:00
KroeseandGitHub ec12039f43 feat: Use deadline-based process timeouts (#1343) 2026-07-28 15:22:47 +02:00
KroeseandGitHub 3c7c3ca1b1 fix: Prevent race when reading PID files (#1342) 2026-07-28 14:22:08 +02:00
KroeseandGitHub 2b27f32cd4 fix: Disk options were applied to the controller (#1341) 2026-07-28 03:30:55 +02:00
KroeseandGitHub 55d1d50284 fix: Retry transient gateway errors in web status (#1340) 2026-07-27 23:49:22 +02:00
KroeseandGitHub 784b73b5b5 feat: Add DISK_OPTIONS support to disk devices (#1339) 2026-07-27 23:48:21 +02:00
KroeseandGitHub 85f00bb9cc docs: Added new DISK_OPTIONS variable (#1338) 2026-07-27 12:04:25 +02:00
KroeseandGitHub efe8732e47 fix: Avoid shadowing PID output variables (#1337) 2026-07-27 12:03:24 +02:00
KroeseandGitHub f6871dd61b fix: Clear invalid PID values in shared reader (#1336) 2026-07-26 17:52:14 +02:00
KroeseandGitHub a713b728ff fix: Use shared PID reader for helper processes (#1335) 2026-07-26 17:41:46 +02:00
KroeseandGitHub 0d74c6ac80 build: Update dependabot config (#1334) 2026-07-26 00:58:36 +02:00
15 changed files with 168 additions and 118 deletions
+7
View File
@@ -1,4 +1,5 @@
version: 2
updates:
- package-ecosystem: docker
directory: /
@@ -6,9 +7,15 @@ updates:
interval: weekly
cooldown:
default-days: 7
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
ignore:
- dependency-name: "*"
update-types:
- version-update:semver-minor
- version-update:semver-patch
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
-e SC2153
-
name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.3.0
uses: hadolint/hadolint-action@v3.4.0
with:
dockerfile: Dockerfile
ignore: DL3008
+1 -1
View File
@@ -8,7 +8,7 @@ ARG TARGETPLATFORM
ARG VERSION_ARG="0.0"
ARG VERSION_CSTRUCT="4.7"
ARG VERSION_PASST="2026_07_16"
ARG VERSION_PASST="2026_07_28"
ARG DEBCONF_NOWARNINGS="yes"
ARG DEBIAN_FRONTEND="noninteractive"
+1
View File
@@ -39,6 +39,7 @@ An empty default means the variable is unset and its value is determined automat
| `DISK_DISCARD` | `unmap` | Discard/TRIM mode for the primary disk. |
| `DISK_ROTATION` | `1` | Rotation rate reported to the guest. Use `1` to identify the disk as an SSD. |
| `DISK_FLAGS` | | Additional options used when creating `qcow2` disks. |
| `DISK_OPTIONS` | | Additional options appended to QEMU disk devices. |
| `ALLOCATE` | `N` | Preallocates space for the data disks. |
| `STORAGE` | `/storage` | Storage directory used for disks, settings, and downloads. |
+15 -5
View File
@@ -7,6 +7,7 @@ set -Eeuo pipefail
: "${DISK_FMT:="raw"}" # Disk file format, 'raw' by default for best performance
: "${DISK_TYPE:=""}" # Device type to be used, "sata", "nvme", "blk" or "scsi"
: "${DISK_FLAGS:=""}" # Specifies the options for use with the qcow2 disk format
: "${DISK_OPTIONS:=""}" # Specifies additional options for the QEMU disk device
: "${DISK_CACHE:="none"}" # Caching mode, can be set to 'writeback' for better performance
: "${DISK_DISCARD:="unmap"}" # Controls whether unmap (TRIM) commands are passed to the host.
: "${DISK_ROTATION:="1"}" # Rotation rate, set to 1 for SSD storage and increase for HDD
@@ -16,6 +17,7 @@ DISK_IO=$(strip "$DISK_IO")
DISK_FMT=$(strip "$DISK_FMT")
DISK_TYPE=$(strip "$DISK_TYPE")
DISK_FLAGS=$(strip "$DISK_FLAGS")
DISK_OPTIONS=$(strip "$DISK_OPTIONS")
DISK_CACHE=$(strip "$DISK_CACHE")
DISK_DISCARD=$(strip "$DISK_DISCARD")
DISK_ROTATION=$(strip "$DISK_ROTATION")
@@ -508,6 +510,9 @@ createDevice () {
[[ -z "${PCI_BUS:-}" && ( "${MACHINE,,}" == pc || "${MACHINE,,}" == pc-i440fx* ) ]] && bus="pci.0"
local options=""
[ -n "$DISK_OPTIONS" ] && options=",${DISK_OPTIONS#,}"
local bootIndex=""
local diskId="data$diskIndex"
[ -n "$diskIndex" ] && bootIndex=",bootindex=$diskIndex"
@@ -520,29 +525,29 @@ createDevice () {
;;
"usb" )
result+=",if=none \
-device usb-storage,drive=${diskId}${bootIndex}${diskSerial}${diskSectors}"
-device usb-storage,drive=${diskId}${bootIndex}${diskSerial}${diskSectors}${options}"
echo "$result"
;;
"nvme" )
result+=",if=none \
-device nvme,drive=${diskId}${bootIndex},serial=deadbeaf${diskIndex}${diskSerial}${diskSectors}"
-device nvme,drive=${diskId}${bootIndex},serial=deadbeaf${diskIndex}${diskSerial}${diskSectors}${options}"
echo "$result"
;;
"ide" | "sata" )
result+=",if=none \
-device ich9-ahci,id=ahci${diskIndex},addr=$diskAddress \
-device ide-hd,drive=${diskId},bus=ahci$diskIndex.0,rotation_rate=$DISK_ROTATION${bootIndex}${diskSerial}${diskSectors}"
-device ide-hd,drive=${diskId},bus=ahci$diskIndex.0,rotation_rate=$DISK_ROTATION${bootIndex}${diskSerial}${diskSectors}${options}"
echo "$result"
;;
"blk" | "virtio-blk" )
result+=",if=none \
-device virtio-blk-pci,drive=${diskId},bus=$bus,addr=$diskAddress,iothread=io2${bootIndex}${diskSerial}${diskSectors}"
-device virtio-blk-pci,drive=${diskId},bus=$bus,addr=$diskAddress,iothread=io2${bootIndex}${diskSerial}${diskSectors}${options}"
echo "$result"
;;
"scsi" | "virtio-scsi" )
result+=",if=none \
-device virtio-scsi-pci,id=${diskId}b,bus=$bus,addr=$diskAddress,iothread=io2,hotplug=off \
-device scsi-hd,drive=${diskId},bus=${diskId}b.0,channel=0,scsi-id=0,lun=0,rotation_rate=$DISK_ROTATION${bootIndex}${diskSerial}${diskSectors}"
-device scsi-hd,drive=${diskId},bus=${diskId}b.0,channel=0,scsi-id=0,lun=0,rotation_rate=$DISK_ROTATION${bootIndex}${diskSerial}${diskSectors}${options}"
echo "$result"
;;
esac
@@ -771,6 +776,11 @@ if [[ "$DISK_FLAGS" =~ [[:space:]] ]]; then
exit 78
fi
if [[ "$DISK_OPTIONS" =~ [[:space:]] ]]; then
error "Invalid DISK_OPTIONS value '$DISK_OPTIONS', spaces are not allowed."
exit 78
fi
if [ -z "$ALLOCATE" ]; then
ALLOCATE="N"
fi
+1 -1
View File
@@ -2,7 +2,7 @@
set -Eeuo pipefail
if enabled "$DEBUG"; then
printf "QEMU arguments:\n\n%s\n\n" "${ARGS// -/$'\n-'}"
printf "QEMU arguments:\n\n %s\n\n" "${ARGS// -/$'\n -'}"
fi
return 0
+4 -4
View File
@@ -254,7 +254,7 @@ if ! touch "$SYSTEM"; then
error "Could not create file $SYSTEM for the system disk." && exit 98
fi
! setOwner "$SYSTEM" && warn "failed to set the owner for \"$SYSTEM\" !"
setOwner "$SYSTEM" || warn "failed to set the owner for \"$SYSTEM\" !"
if [[ "${FS,,}" == "btrfs" ]]; then
{ chattr +C "$SYSTEM"; } || :
@@ -329,7 +329,7 @@ fakeroot -- bash -c "set -Eeu;\
rm -rf "$MOUNT"
echo "$BASE" > "$STORAGE/dsm.ver"
! setOwner "$STORAGE/dsm.ver" && warn "failed to set the owner for \"$STORAGE/dsm.ver\" !"
setOwner "$STORAGE/dsm.ver" || warn "failed to set the owner for \"$STORAGE/dsm.ver\" !"
if [[ "$URL" == "file://$STORAGE/$BASE.pat" ]]; then
rm -f "$PAT"
@@ -338,11 +338,11 @@ else
fi
if [ -f "$STORAGE/$BASE.pat" ]; then
! setOwner "$STORAGE/$BASE.pat" && warn "failed to set the owner for \"$STORAGE/$BASE.pat\" !"
setOwner "$STORAGE/$BASE.pat" || warn "failed to set the owner for \"$STORAGE/$BASE.pat\" !"
fi
mv -f "$BOOT" "$STORAGE/$BASE.boot.img"
! setOwner "$STORAGE/$BASE.boot.img" && warn "failed to set the owner for \"$STORAGE/$BASE.boot.img\" !"
setOwner "$STORAGE/$BASE.boot.img" || warn "failed to set the owner for \"$STORAGE/$BASE.boot.img\" !"
rm -rf "$TMP"
+77 -54
View File
@@ -405,36 +405,6 @@ natGuestIP() {
return 1
}
kernelAtLeast() {
local major="$1"
local minor="${2:-0}"
(( KERNEL > major || (KERNEL == major && MINOR >= minor) ))
}
canBindToDevice() {
local dev="$1"
[ -n "$dev" ] || return 1
kernelAtLeast 5 7 || return 1
[ -d "/sys/class/net/$dev" ] || return 1
command -v python3 > /dev/null 2>&1 || return 0
python3 - "$dev" > /dev/null 2>&1 <<'PY'
import socket
import sys
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.setsockopt(
socket.SOL_SOCKET,
socket.SO_BINDTODEVICE,
sys.argv[1].encode() + b"\0",
)
PY
}
# ######################################
# DNS / port helpers
# ######################################
@@ -449,6 +419,7 @@ configureDNS() {
local gateway="$6"
local upstream="${7:-}"
local arguments="$DNSMASQ_OPTS"
local pid
if ! echo "$gateway" > /run/shm/qemu.gw; then
error "Failed to write gateway file."
@@ -458,7 +429,10 @@ configureDNS() {
enabled "${DNSMASQ_DISABLE:-}" && return 0
enabled "$DEBUG" && echo "Starting dnsmasq daemon..."
[ -s "$DNSMASQ_PID" ] && pKill "$(<"$DNSMASQ_PID")"
if readPidFile pid "$DNSMASQ_PID"; then
pKill "$pid"
fi
rm -f "$DNSMASQ_PID"
if isNAT; then
@@ -518,7 +492,7 @@ configureDNS() {
arguments+=" --log-facility=$log"
arguments=$(echo "$arguments" | sed 's/\t/ /g' | tr -s ' ' | sed 's/^ *//')
enabled "$DEBUG" && printf "Dnsmasq arguments:\n\n%s\n\n" "${arguments// -/$'\n-'}"
enabled "$DEBUG" && printf "Dnsmasq arguments:\n\n %s\n\n" "${arguments// -/$'\n -'}"
{ $DNSMASQ ${arguments:+ $arguments}; local rc=$?; } || :
@@ -541,11 +515,12 @@ configureDNS() {
return 0
}
getHostPorts() {
normalizePorts() {
local list="${HOST_PORTS// /},"
local port ports=""
local mode="${1:-tcp}"
local list="$1"
local mode="${2:-tcp}"
local port num
local ports=""
for port in ${list//,/ }; do
@@ -554,31 +529,78 @@ getHostPorts() {
case "$mode" in
"tcp" )
[[ "$port" == *"/udp" ]] && continue
local num="${port%/tcp}"
num="${port%/tcp}"
[ -n "$num" ] && ports+="$num,"
;;
"all" )
if [[ "$port" == *"/udp" ]]; then
local num="${port%/udp}"
num="${port%/udp}"
[ -n "$num" ] && ports+="$num/udp,"
else
local num="${port%/tcp}"
num="${port%/tcp}"
[ -n "$num" ] && ports+="$num/tcp,"
fi
continue
;;
*)
return 1
;;
esac
[ -n "$num" ] && ports+="$num,"
done
# Remove duplicates
ports=$(echo "${ports//,,/,}," | awk 'BEGIN{RS=ORS=","} !seen[$0]++' | sed 's/,*$//g')
echo "${ports//,,/,}," | awk 'BEGIN{RS=ORS=","} !seen[$0]++' | sed 's/,*$//g'
return 0
}
getReservedPorts() {
local list=""
local mode="${1:-tcp}"
# Reserve the DNS port while the internal dnsmasq resolver is active.
if ! enabled "${DNSMASQ_DISABLE:-}" && ! isNAT; then
list+="53/tcp,53/udp,"
fi
# WEB_PORT and WSD_PORT are intentionally not reserved. In non-DHCP modes,
# closeWeb() releases both before NAT or user-mode forwarding is configured,
# allowing WEB_PORT (normally 5000) to be handed over to DSM.
normalizePorts "$list" "$mode"
return $?
}
getCustomHostPorts() {
local mode="${1:-tcp}"
local reserved user port
local ports=""
reserved=$(getReservedPorts "all")
user=$(normalizePorts "$HOST_PORTS" "all")
for port in ${user//,/ }; do
[[ ",$reserved," == *",$port,"* ]] && continue
ports+="$port,"
done
normalizePorts "$ports" "$mode"
return 0
}
getHostPorts() {
local mode="${1:-tcp}"
local reserved custom
# Merge internal reservations with user-defined host ports without mutating HOST_PORTS.
# User entries already covered by an internal reservation are silently ignored.
reserved=$(getReservedPorts "all")
custom=$(getCustomHostPorts "all")
normalizePorts "$reserved,$custom" "$mode"
echo "$ports"
return 0
}
@@ -588,8 +610,9 @@ getUserPorts() {
local list="$defaults,${USER_PORTS// /},"
local ports=""
local userport hostport exclude
local userport hostport exclude reserved
reserved=$(getReservedPorts "all")
exclude=$(getHostPorts "all")
for userport in ${list//,/ }; do
@@ -611,7 +634,9 @@ getUserPorts() {
if [[ "$num/$proto" == "$hostport" ]]; then
if [[ "$hostport" != "${WEB_PORT:-}/tcp" ]]; then
if [[ ",$reserved," == *",$hostport,"* ]]; then
warn "Could not assign port $hostport to \"USER_PORTS\" because it is reserved by the container!"
elif [[ "$hostport" != "${WEB_PORT:-}/tcp" ]]; then
warn "Could not assign port $hostport to \"USER_PORTS\" because it is already in \"HOST_PORTS\"!"
fi
@@ -659,7 +684,6 @@ getSlirp() {
getPasst() {
local list port
local bind="$UPLINK"
local tcp="" udp="" args=""
list=$(getUserPorts)
@@ -689,12 +713,8 @@ getPasst() {
tcp="${tcp%,}"
udp="${udp%,}"
if canBindToDevice "$DEV"; then
bind="%$DEV"
fi
[ -n "$tcp" ] && args+=" -t $bind/$tcp"
[ -n "$udp" ] && args+=" -u $bind/$udp"
[ -n "$tcp" ] && args+=" -t $tcp"
[ -n "$udp" ] && args+=" -u $udp"
echo "$args"
return 0
@@ -1901,7 +1921,10 @@ validateHost() {
validateHostPorts() {
if isNAT && [[ "${HOST_PORTS,,}" == *"/udp"* ]]; then
local custom
custom=$(getCustomHostPorts "all")
if isNAT && [[ "$custom" == *"/udp"* ]]; then
warn "UDP ports in \"HOST_PORTS\" are not yet implemented for NAT networking."
fi
+8 -18
View File
@@ -67,16 +67,8 @@ displayReason() {
readQemuPid() {
local -n _pid="$1"
local file
for file in "$QEMU_START_PID" "$QEMU_PID"; do
if [ -s "$file" ] && read -r _pid < "$file"; then
return 0
fi
done
return 1
readPidFile "$1" "$QEMU_START_PID" && return 0
readPidFile "$1" "$QEMU_PID"
}
qemuPidFile() {
@@ -100,16 +92,14 @@ waitQemuExit() {
waitQemuPid() {
local -n _pid="$1"
local cnt=0 value
local cnt=0
while ! readQemuPid value; do
while ! readQemuPid "$1"; do
sleep 0.02
cnt=$((cnt + 1))
(( cnt >= 50 )) && return 1
done
_pid="$value"
return 0
}
@@ -118,8 +108,8 @@ forceKillQemu() {
local reason="$1"
local pid display
! readQemuPid pid && return 0
! isAlive "$pid" && return 0
readQemuPid pid || return 0
isAlive "$pid" || return 0
display=$(displayReason "$reason")
error "Forcefully terminating $(app), reason: $display..."
@@ -315,7 +305,7 @@ waitForShutdown() {
local slp=$!
# Stop waiting if the process has exited
! isAlive "$pid" && break
isAlive "$pid" || break
# Workaround for stale/zombie QEMU pid file
[ ! -s "$QEMU_START_PID" ] && [ ! -s "$QEMU_PID" ] && break
@@ -382,7 +372,7 @@ graceful_shutdown() {
finish "$code"
}
! enabled "$SHUTDOWN" && return 0
enabled "$SHUTDOWN" || return 0
[ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT"
if interactive; then
+1 -1
View File
@@ -47,7 +47,7 @@ checkSse42() {
if ! hasFlag "sse4_2"; then
error "Your CPU does not have the SSE4 instruction set that Virtual DSM requires!"
! enabled "$DEBUG" && exit 88
enabled "$DEBUG" || exit 88
fi
return 0
+3 -3
View File
@@ -209,7 +209,7 @@ normalizeRamSize() {
fi
RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
! numfmt --from=iec "$RAM_SIZE" &>/dev/null && error "Invalid RAM_SIZE: $RAM_SIZE" && exit 16
numfmt --from=iec "$RAM_SIZE" &>/dev/null || { error "Invalid RAM_SIZE: $RAM_SIZE" && exit 16; }
wanted=$(numfmt --from=iec "$RAM_SIZE")
[ "$wanted" -lt "$RAM_MINIMUM" ] && error "RAM_SIZE is too low: $RAM_SIZE" && exit 16
@@ -254,7 +254,7 @@ checkKvm() {
fi
if ! grep -qw "sse4_2" <<< "$flags"; then
error "Your CPU does not have the SSE4 instruction set that Virtual DSM requires!"
! enabled "$DEBUG" && exit 88
enabled "$DEBUG" || exit 88
fi
fi
fi
@@ -275,7 +275,7 @@ checkKvm() {
error "KVM acceleration is not available $KVM_ERR, this will cause the machine to run about 10 times slower."
error "See the FAQ for possible causes, or disable acceleration by adding the \"KVM=N\" variable (not recommended)." ;;
esac
! enabled "$DEBUG" && exit 88
enabled "$DEBUG" || exit 88
fi
fi
+6 -7
View File
@@ -73,7 +73,7 @@ startHostBinary() {
pid=$!
fi
echo "$pid" > "$HOST_PID"
printf '%s\n' "$pid" > "$HOST_PID"
return 0
}
@@ -82,23 +82,22 @@ waitForSocket() {
local socket="$1"
local exit_code="$2"
local pid cnt=0
local timeout=5 pid
local deadline=$((SECONDS + timeout))
while [ ! -S "$socket" ]; do
if ! read -r pid < "$HOST_PID" || ! isAlive "$pid"; then
if ! readPidFile pid "$HOST_PID" || ! isAlive "$pid"; then
error "qemu-host exited unexpectedly!"
exit "$exit_code"
fi
sleep 0.1
cnt=$((cnt + 1))
if (( cnt > 50 )); then
if (( SECONDS >= deadline )); then
error "Failed to create qemu-host socket: $socket"
exit "$exit_code"
fi
sleep 0.1
done
return 0
+2 -2
View File
@@ -64,7 +64,7 @@ stopWebServer() {
local pid
if [ -s "$WEB_PID" ] && read -r pid < "$WEB_PID" && [ -n "$pid" ]; then
if readPidFile pid "$WEB_PID"; then
pKill "$pid" 2
if isAlive "$pid"; then
@@ -88,7 +88,7 @@ stopWebsocketServer() {
local pid
if [ -s "$WSD_PID" ] && read -r pid < "$WSD_PID" && [ -n "$pid" ]; then
if readPidFile pid "$WSD_PID"; then
pKill "$pid" 2
if isAlive "$pid"; then
+31 -18
View File
@@ -7,6 +7,24 @@ info () { printf "%b%s%b" "\E[1;34m \E[1;36m" "${1:-}" "\E[0m\n"; }
error () { printf "%b%s%b" "\E[1;31m " "ERROR: ${1:-}" "\E[0m\n" >&2; }
warn () { printf "%b%s%b" "\E[1;31m " "Warning: ${1:-}" "\E[0m\n" >&2; }
readPidFile() {
local -n _pid="$1"
_pid=""
if ! _pid=$(cat -- "$2" 2>/dev/null); then
_pid=""
return 1
fi
if [[ ! "$_pid" =~ ^[1-9][0-9]*$ ]]; then
_pid=""
return 1
fi
return 0
}
hasFlag() {
# Match a whitespace-delimited token in /proc/cpuinfo
@@ -118,14 +136,13 @@ isAlive() {
waitPid() {
local i=0
local pid="$1"
local timeout="${2:-10}"
local deadline=$((SECONDS + timeout))
while [ -n "$pid" ] && isAlive "$pid"; do
(( SECONDS >= deadline )) && return 1
sleep 0.2
i=$((i + 1))
(( i >= timeout * 5 )) && return 1
done
return 0
@@ -133,18 +150,16 @@ waitPid() {
waitPidFile() {
local i=0 pid
local pid
local file="$1"
local timeout="${2:-10}"
local deadline=$((SECONDS + timeout))
[ ! -s "$file" ] && return 0
! read -r pid <"$file" && return 0
[ -z "$pid" ] && return 0
readPidFile pid "$file" || return 0
while [ -s "$file" ] && isAlive "$pid"; do
(( SECONDS >= deadline )) && return 1
sleep 0.2
i=$((i + 1))
(( i >= timeout * 5 )) && return 1
done
rm -f -- "$file"
@@ -167,19 +182,19 @@ pKill() {
fWait() {
local i=0
local name="$1"
local timeout="${2:-10}"
local deadline=$((SECONDS + timeout))
[ -z "$name" ] && return 0
while pgrep -f -l "$name" >/dev/null; do
sleep 0.2
i=$((i + 1))
if (( i >= timeout * 5 )); then
if (( SECONDS >= deadline )); then
warn "Timed out while waiting for process: $name"
break
fi
sleep 0.2
done
return 0
@@ -203,9 +218,7 @@ sKill() {
local pid
local file="$1"
[ ! -s "$file" ] && return 0
! read -r pid <"$file" && return 0
[ -z "$pid" ] && return 0
readPidFile pid "$file" || return 0
if isAlive "$pid"; then
{ kill -15 -- "$pid" || :; } 2>/dev/null
@@ -243,7 +256,7 @@ setOwner() {
uid=$(stat -c '%u' "$dir") || return 1
gid=$(stat -c '%g' "$dir") || return 1
! chown "$uid:$gid" "$file" && return 1
chown "$uid:$gid" "$file" || return 1
return 0
}
@@ -254,7 +267,7 @@ makeDir() {
local dir uid gid
[ -d "$path" ] && return 0
! mkdir -p "$path" && return 1
mkdir -p "$path" || return 1
dir=$(dirname -- "$path")
+10 -3
View File
@@ -71,6 +71,13 @@ function processInfo() {
var response = request;
request = null;
var status = response.status;
if (status == 502 || status == 503 || status == 504) {
schedule();
return true;
}
var msg = response.responseText;
if (msg == null || msg.length == 0) {
@@ -83,9 +90,9 @@ function processInfo() {
return false;
}
var notFound = (response.status == 404);
var notFound = (status == 404);
if (response.status == 200) {
if (status == 200) {
if (msg.toLowerCase().indexOf("<html>") !== -1) {
notFound = true;
} else {
@@ -103,7 +110,7 @@ function processInfo() {
return true;
}
setError("Error: Received statuscode " + response.status);
setError("Error: Received statuscode " + status);
return false;
} catch (e) {