Compare commits

...

7 Commits

Author SHA1 Message Date
Kroese f0b3967927 fix: Unbound USB variable (#1860) 2026-07-15 19:39:32 +02:00
Kroese 3b2a26e303 fix: Backwards compatibility for USB state (#1859) 2026-07-15 18:40:29 +02:00
Kroese 463935baf2 fix: Make changing ownership non-fatal (#1858) 2026-07-15 18:27:08 +02:00
Kroese 50d5f4fc09 fix: Remove deprecated Samba socket address (#1857) 2026-07-15 17:03:33 +02:00
Kroese 9421d31b91 fix: Preserve installation ISO when marker creation fails (#1856) 2026-07-15 16:25:48 +02:00
Kroese 7642a17b57 feat: Improve curl error reporting (#1855) 2026-07-15 11:34:26 +02:00
Kroese b1ff5da11a feat: Improve wget error reporting (#1854) 2026-07-15 10:29:15 +02:00
4 changed files with 286 additions and 178 deletions
+3 -6
View File
@@ -204,8 +204,7 @@ finishInstall() {
if [[ "$iso" == "$STORAGE/"* ]]; then if [[ "$iso" == "$STORAGE/"* ]]; then
if ! setOwner "$iso"; then if ! setOwner "$iso"; then
error "Failed to set the owner for \"$iso\" !" warn "failed to set the owner for \"$iso\" !"
return 1
fi fi
fi fi
@@ -221,8 +220,7 @@ finishInstall() {
cp -f /etc/version "$file" || return 1 cp -f /etc/version "$file" || return 1
if ! setOwner "$file"; then if ! setOwner "$file"; then
error "Failed to set the owner for \"$file\" !" warn "Failed to set the owner for \"$file\" !"
return 1
fi fi
if [[ "$iso" == "$STORAGE/"* ]]; then if [[ "$iso" == "$STORAGE/"* ]]; then
@@ -1261,8 +1259,7 @@ buildImage() {
mv -f "$out" "$BOOT" || return 1 mv -f "$out" "$BOOT" || return 1
if ! setOwner "$BOOT"; then if ! setOwner "$BOOT"; then
error "Failed to set the owner for \"$BOOT\" !" warn "Failed to set the owner for \"$BOOT\" !"
return 1
fi fi
return 0 return 0
+178 -90
View File
@@ -5,46 +5,85 @@ handleCurlError() {
local code="$1" local code="$1"
local server="$2" local server="$2"
local reason="${3:-}"
local signal=""
if [ -n "$reason" ] && (( code <= 125 )); then
error "Request to $server servers failed: ${reason%.}."
return 1
fi
case "$code" in case "$code" in
1) error "Unsupported protocol!" ;; 126) error "The curl command could not be executed." ;;
2) error "Failed to initialize curl!" ;; 127) error "The curl command was not found." ;;
3) error "The URL format is malformed!" ;;
5) error "Failed to resolve address of proxy host!" ;;
6) error "Failed to resolve $server servers! Is there an Internet connection?" ;;
7) error "Failed to contact $server servers! Is there an Internet connection or is the server down?" ;;
8) error "$server servers returned a malformed HTTP response!" ;;
16) error "A problem was detected in the HTTP2 framing layer!" ;;
22) error "$server servers returned a failing HTTP status code!" ;;
23) error "Failed at writing Windows media to disk! Out of disk space or permission error?" ;;
26) error "Failed to read Windows media from disk!" ;;
27) error "Ran out of memory during download!" ;;
28) error "Connection timed out to $server server!" ;;
35) error "SSL connection error from $server server!" ;;
36) error "Failed to continue earlier download!" ;;
52) error "Received no data from the $server server!" ;;
63) error "$server servers returned an unexpectedly large response!" ;;
126) error "Curl command cannot be executed!" ;;
127) error "Curl command not found!" ;;
*) *)
if (( code <= 125 )); then if (( code < 129 )); then
# Must be some other server or network error (possibly with this specific request/file) error "Request to $server servers failed with curl exit status $code."
# This is when accounting for all possible errors in the curl manual assuming a correctly formed return 1
# curl command and an HTTP(S) request, using only the curl features we're using, and a sane build.
error "Miscellaneous server or network error, reason: $code"
else
case "$(kill -l "$code" 2>/dev/null || true)" in
INT) error "Curl was interrupted!" ;;
SEGV | ABRT) error "Curl crashed! Please report any core dumps to curl developers." ;;
*) error "Curl terminated due to fatal signal $code !" ;;
esac
fi fi
signal=$(kill -l "$((code - 128))" 2>/dev/null || true)
case "$signal" in
INT) error "Curl was interrupted." ;;
SEGV | ABRT) error "Curl crashed with signal $signal." ;;
"") error "Curl terminated with exit status $code." ;;
*) error "Curl terminated due to signal $signal." ;;
esac
;; ;;
esac esac
return 1 return 1
} }
curlRequest() {
local output="$1"
local server="$2"
local agent="$3"
shift 3
local log reason
local rc=0 response=""
if ! log=$(mktemp); then
error "Failed to create a temporary curl log."
return 1
fi
{
response=$(LC_ALL=C curl \
--silent \
--show-error \
--max-time 30 \
--user-agent "$agent" \
--fail \
--proto =https \
--tlsv1.2 \
--http1.1 \
"$@" 2>"$log")
rc=$?
} || :
if (( rc != 0 )); then
reason=$(sed -nE 's/^curl: \([0-9]+\) //p' "$log" | tail -n 1)
rm -f "$log"
handleCurlError "$rc" "$server" "$reason"
return 1
fi
rm -f "$log"
if [ -n "$output" ]; then
printf -v "$output" '%s' "$response"
fi
return 0
}
getAgent() { getAgent() {
local browser_version local browser_version
@@ -62,15 +101,14 @@ downloadWindows() {
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local rc=0
local ovToken="" ovTicks="" ovTime="" local ovToken="" ovTicks="" ovTime=""
local skuId="" skuUrl="" skuJson="" local skuId="" skuUrl="" skuJson=""
local linkUrl="" linkJson="" link="" local linkUrl="" linkJson="" link=""
local language="" orgId="" local language="" orgId="" ovData=""
local instance="" vlsUrl="" ovUrl="" ovData="" local instance="" vlsUrl="" ovUrl=""
local session="" agent="" type="" local session="" agent="" type=""
local winVer="" page="" productId="" local winVer="" page="" productId=""
local profile="606624d44113" local rc=0 profile="606624d44113"
agent=$(getAgent) agent=$(getAgent)
language=$(getLanguage "$lang" "name") language=$(getLanguage "$lang" "name")
@@ -102,10 +140,11 @@ downloadWindows() {
# Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden # Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden
# Remove "Accept" header that curl sends by default # Remove "Accept" header that curl sends by default
enabled "$DEBUG" && echo "Parsing download page: ${url}" enabled "$DEBUG" && echo "Parsing download page: ${url}"
page=$(curl --silent --max-time 30 --user-agent "$agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
handleCurlError "$?" "Microsoft" curlRequest page "Microsoft" "$agent" \
return $? --header "Accept:" \
} --max-filesize 1M \
-- "$url" || return 1
enabled "$DEBUG" && echo -n "Getting Product edition ID: " enabled "$DEBUG" && echo -n "Getting Product edition ID: "
productId=$(echo "$page" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16) productId=$(echo "$page" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)
@@ -124,11 +163,11 @@ downloadWindows() {
enabled "$DEBUG" && echo "Getting Session ID: $session" enabled "$DEBUG" && echo "Getting Session ID: $session"
# Permit Session ID # Permit Session ID
curl --silent --max-time 30 --output /dev/null --user-agent "$agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$vlsUrl" || { curlRequest "" "Microsoft" "$agent" \
# This should only happen if there's been some change to how this API works --output /dev/null \
handleCurlError "$?" "Microsoft" --header "Accept:" \
return $? --max-filesize 100K \
} -- "$vlsUrl" || return 1
# Microsoft download "protection" also requires an ov-df.microsoft.com request/reply # Microsoft download "protection" also requires an ov-df.microsoft.com request/reply
# 1) Request mdt.js to get w and rticks. InstanceId is (currently) constant. # 1) Request mdt.js to get w and rticks. InstanceId is (currently) constant.
@@ -138,10 +177,10 @@ downloadWindows() {
enabled "$DEBUG" && echo -n "Getting OV data: " enabled "$DEBUG" && echo -n "Getting OV data: "
ovData=$(curl --silent --max-time 30 --user-agent "$agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$ovUrl") || { curlRequest ovData "Microsoft" "$agent" \
handleCurlError "$?" "Microsoft" --header "Accept:" \
return $? --max-filesize 1M \
} -- "$ovUrl" || return 1
if [[ $ovData =~ [\?\&]w=([A-Fa-f0-9]+) ]]; then if [[ $ovData =~ [\?\&]w=([A-Fa-f0-9]+) ]]; then
ovToken="${BASH_REMATCH[1]}" ovToken="${BASH_REMATCH[1]}"
@@ -167,19 +206,21 @@ downloadWindows() {
enabled "$DEBUG" && echo "Sending OV reply: $instance" enabled "$DEBUG" && echo "Sending OV reply: $instance"
curl --silent --max-time 30 --output /dev/null --user-agent "$agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$ovUrl" || { curlRequest "" "Microsoft" "$agent" \
# This should only happen if there's been some change to how this API works --output /dev/null \
handleCurlError "$?" "Microsoft" --header "Accept:" \
return $? --max-filesize 100K \
} -- "$ovUrl" || return 1
enabled "$DEBUG" && echo -n "Getting language SKU ID: " enabled "$DEBUG" && echo -n "Getting language SKU ID: "
skuUrl="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$productId&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session" skuUrl="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$productId&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session"
skuJson=$(curl --silent --max-time 30 --request GET --user-agent "$agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$skuUrl") || {
handleCurlError "$?" "Microsoft" curlRequest skuJson "Microsoft" "$agent" \
return $? --referer "$url" \
} --header "Accept:" \
--max-filesize 100K \
-- "$skuUrl" || return 1
{ skuId=$(echo "$skuJson" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; rc=$?; } || : { skuId=$(echo "$skuJson" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; rc=$?; } || :
@@ -196,10 +237,12 @@ downloadWindows() {
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed) # If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
linkUrl="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$skuId&friendlyFileName=undefined&Locale=en-US&sessionID=$session" linkUrl="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$skuId&friendlyFileName=undefined&Locale=en-US&sessionID=$session"
linkJson=$(curl --silent --max-time 30 --request GET --user-agent "$agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$linkUrl") || {
handleCurlError "$?" "Microsoft" curlRequest linkJson "Microsoft" "$agent" \
return $? --referer "$url" \
} --header "Accept:" \
--max-filesize 100K \
-- "$linkUrl" || return 1
if ! [ "$linkJson" ]; then if ! [ "$linkJson" ]; then
# This should only happen if there's been some change to how this API works # This should only happen if there's been some change to how this API works
@@ -279,10 +322,11 @@ downloadWindowsEval() {
local url="https://www.microsoft.com/en-us/evalcenter/download-$winVer" local url="https://www.microsoft.com/en-us/evalcenter/download-$winVer"
enabled "$DEBUG" && echo "Parsing download page: ${url}" enabled "$DEBUG" && echo "Parsing download page: ${url}"
page=$(curl --silent --max-time 30 --user-agent "$agent" --location --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
handleCurlError "$?" "Microsoft" curlRequest page "Microsoft" "$agent" \
return $? --location \
} --max-filesize 1M \
-- "$url" || return 1
if ! [ "$page" ]; then if ! [ "$page" ]; then
# This should only happen if there's been some change to where this download page is located # This should only happen if there's been some change to where this download page is located
@@ -346,11 +390,12 @@ downloadWindowsEval() {
# Follow redirect so proceeding log message is useful # Follow redirect so proceeding log message is useful
# This is a request we make that Fido doesn't # This is a request we make that Fido doesn't
link=$(curl --silent --max-time 30 --user-agent "$agent" --location --output /dev/null --silent --write-out "%{url_effective}" --head --fail --proto =https --tlsv1.2 --http1.1 -- "$link") || { curlRequest link "Microsoft" "$agent" \
# This should only happen if the Microsoft servers are down --location \
handleCurlError "$?" "Microsoft" --output /dev/null \
return $? --write-out "%{url_effective}" \
} --head \
-- "$link" || return 1
case "${PLATFORM,,}" in case "${PLATFORM,,}" in
"x64" ) "x64" )
@@ -523,13 +568,12 @@ getESD() {
local version="$2" local version="$2"
local lang="$3" local lang="$3"
local desc="$4" local desc="$4"
local rc=0
local file result culture local file result culture
local language edition catalog local language edition catalog
local xmlFile="products.xml" local xmlFile="products.xml"
local esdFile="esd_edition.xml" local esdFile="esd_edition.xml"
local filterFile="products_filter.xml" local filterFile="products_filter.xml"
local query local log query rc=0 reason=""
file=$(getCatalog "$version" "file") file=$(getCatalog "$version" "file")
catalog=$(getCatalog "$version" "url") catalog=$(getCatalog "$version" "url")
@@ -551,13 +595,36 @@ getESD() {
return 1 return 1
fi fi
{ wget "$catalog" -O "$dir/$file" -q --timeout=30 --no-http-keep-alive; rc=$?; } || : log=$(mktemp)
msg="Failed to download $catalog" {
(( rc == 3 )) && error "$msg , cannot write file (disk full?)" && return 1 LC_ALL=C wget "$catalog" -O "$dir/$file" --no-verbose --timeout=30 \
(( rc == 4 )) && error "$msg , network failure!" && return 1 --no-http-keep-alive --output-file="$log"
(( rc == 8 )) && error "$msg , server issued an error response!" && return 1 rc=$?
(( rc != 0 )) && error "$msg , reason: $rc" && return 1 } || :
if (( rc != 0 )); then
reason=$(sed -n \
-e 's/^wget: //p' \
-e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \
"$log" | tail -n 1)
msg="Failed to download $catalog"
if (( rc == 3 )); then
error "$msg because the file could not be written (disk full?)."
elif [ -n "$reason" ]; then
error "$msg: ${reason%.}."
else
error "$msg with exit status $rc."
fi
rm -f "$log"
return 1
fi
rm -f "$log"
if [[ "$file" == *".xml" ]]; then if [[ "$file" == *".xml" ]]; then
@@ -703,20 +770,22 @@ downloadFile() {
local size="$4" local size="$4"
local lang="$5" local lang="$5"
local desc="$6" local desc="$6"
local reason=""
local msg="Downloading $desc" local msg="Downloading $desc"
local rc total total_gb progress domain dots agent space folder local rc total total_gb progress log
local domain dots agent space folder
agent=$(getAgent) agent=$(getAgent)
if [ -n "$size" ] && [[ "$size" != "0" ]]; then if [ -n "$size" ] && [[ "$size" != "0" ]]; then
folder=$(dirname -- "$iso") folder=$(dirname -- "$iso")
if ! space=$(df --output=avail -B 1 "$folder" | tail -n 1); then if ! space=$(df --output=avail -B 1 "$folder" | tail -n 1); then
error "Failed to check free space in $folder!" error "Failed to check free space in $folder!"
return 1 return 1
fi fi
total_gb=$(formatBytes "$space") total_gb=$(formatBytes "$space")
(( size > space )) && error "Not enough free space to download file, only $total_gb left!" && return 1 (( size > space )) && error "Not enough free space to download file, only $total_gb left!" && return 1
fi fi
@@ -740,12 +809,27 @@ downloadFile() {
fi fi
info "$msg..." info "$msg..."
log=$(mktemp)
enabled "$DEBUG" && echo "Downloading: $url" enabled "$DEBUG" && echo "Downloading: $url"
{ wget "$url" -O "$iso" --continue -q --timeout=30 --no-http-keep-alive --user-agent "$agent" --show-progress "$progress"; rc=$?; } || : {
LC_ALL=C wget "$url" -O "$iso" --continue --no-verbose --timeout=30 \
--no-http-keep-alive --user-agent "$agent" --show-progress "$progress" \
--output-file="$log"
rc=$?
} || :
fKill "progress.sh" fKill "progress.sh"
if (( rc != 0 )); then
reason=$(sed -n \
-e 's/^wget: //p' \
-e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \
"$log" | tail -n 1)
fi
rm -f "$log"
if (( rc == 0 )) && [ -f "$iso" ]; then if (( rc == 0 )) && [ -f "$iso" ]; then
if ! total=$(stat -c%s "$iso"); then if ! total=$(stat -c%s "$iso"); then
@@ -754,26 +838,30 @@ downloadFile() {
fi fi
total_gb=$(formatBytes "$total") total_gb=$(formatBytes "$total")
if [ "$total" -lt 100000000 ]; then if [ "$total" -lt 100000000 ]; then
error "Invalid download link: $url (is only $total_gb ?). Please report this at $SUPPORT/issues" error "Invalid download link: $url (is only $total_gb ?). Please report this at $SUPPORT/issues"
return 1 return 1
fi fi
verifyFile "$iso" "$size" "$total" "$sum" || return 1 verifyFile "$iso" "$size" "$total" "$sum" || return 1
isCompressed "$url" && UNPACK="Y" isCompressed "$url" && UNPACK="Y"
html "Download finished successfully..." html "Download finished successfully..."
return 0 return 0
fi fi
msg="Failed to download $url" msg="Failed to download $url"
(( rc == 3 )) && error "$msg , cannot write file (disk full?)" && return 1
(( rc == 4 )) && error "$msg , network failure!" && return 1
(( rc == 8 )) && error "$msg , server issued an error response! Please report this at $SUPPORT/issues" && return 1
error "$msg , reason: $rc" if (( rc == 3 )); then
error "$msg because the file could not be written (disk full?)."
elif [ -n "$reason" ]; then
error "$msg: ${reason%.}."
else
error "$msg with exit status $rc."
fi
return 1 return 1
} }
@@ -875,7 +963,7 @@ downloadImage() {
fi fi
tryDownload "$iso" "$MIDO_URL" "$sum" "$size" "$lang" "$desc" "$seconds" && return 0 tryDownload "$iso" "$MIDO_URL" "$sum" "$size" "$lang" "$desc" "$seconds" && return 0
fi fi
fi fi
+12 -4
View File
@@ -151,10 +151,18 @@ markWindowsBooted() {
# Remove CD-ROM ISO after install # Remove CD-ROM ISO after install
! ready && return 0 ! ready && return 0
touch "$file" if ! touch "$file"; then
! setOwner "$file" && error "Failed to set the owner for \"$file\" !" warn "failed to create Windows installation marker!"
return 0
fi
if ! setOwner "$file"; then
rm -f "$file"
warn "failed to set the owner for \"$file\" !"
return 0
fi
if ! disabled "$REMOVE"; then if ! disabled "$REMOVE"; then
rm -f "$BOOT" 2>/dev/null || true rm -f "$BOOT" 2>/dev/null || true
fi fi
+93 -78
View File
@@ -3,15 +3,16 @@ set -Eeuo pipefail
: "${SAMBA:="Y"}" # Enable Samba : "${SAMBA:="Y"}" # Enable Samba
: "${SAMBA_DEBUG:="N"}" # Disable debug : "${SAMBA_DEBUG:="N"}" # Disable debug
: "${SAMBA_CONFIG:="/etc/samba/smb.conf"}"
tmp="/tmp/smb"
rm -rf "$tmp"
DDN_PID="/var/run/wsdd.pid" DDN_PID="/var/run/wsdd.pid"
NMB_PID="/var/run/samba/nmbd.pid" NMB_PID="/var/run/samba/nmbd.pid"
SMB_PID="/var/run/samba/smbd.pid" SMB_PID="/var/run/samba/smbd.pid"
rm -f "$SMB_PID" "$NMB_PID" "$DDN_PID" if ! rm -f "$SMB_PID" "$NMB_PID" "$DDN_PID"; then
error "Failed to clean Samba PID files!"
return 0
fi
disabled "$SAMBA" && return 0 disabled "$SAMBA" && return 0
disabled "$NETWORK" && return 0 disabled "$NETWORK" && return 0
@@ -19,23 +20,23 @@ disabled "$NETWORK" && return 0
configureNetwork() { configureNetwork() {
if enabled "$DHCP"; then if enabled "$DHCP"; then
socket="$UPLINK"
hostname="$UPLINK" hostname="$UPLINK"
interfaces="$DEV" interfaces="$DEV"
return 0
fi
hostname="host.lan"
if isUserMode; then
interfaces="lo"
else else
hostname="host.lan" interfaces="$BRIDGE"
fi
if isUserMode; then if [ -n "${SAMBA_INTERFACE:-}" ]; then
interfaces="lo" interfaces+=",$SAMBA_INTERFACE"
socket="127.0.0.1"
else
socket="$IP"
interfaces="$BRIDGE"
fi
if [ -n "${SAMBA_INTERFACE:-}" ]; then
interfaces+=",$SAMBA_INTERFACE"
fi
fi fi
return 0 return 0
@@ -46,25 +47,29 @@ writeReadme() {
local dir="$1" local dir="$1"
local ref="$2" local ref="$2"
{ echo "--------------------------------------------------------" if ! {
echo " $APP for $ENGINE v$(</etc/version)..." echo "--------------------------------------------------------"
echo " For support visit $SUPPORT" echo " $APP for $ENGINE v$(</etc/version)..."
echo "--------------------------------------------------------" echo " For support visit $SUPPORT"
echo "" echo "--------------------------------------------------------"
echo "Using this folder you can exchange files with the host machine." echo ""
echo "" echo "Using this folder you can exchange files with the host machine."
echo "To select a folder on the host for this purpose, include the following bind mount in your compose file:" echo ""
echo "" echo "To select a folder on the host for this purpose, include the following bind mount in your compose file:"
echo " volumes:" echo ""
echo " - \"./example:${ref}\"" echo " volumes:"
echo "" echo " - \"./example:${ref}\""
echo "Or in your run command:" echo ""
echo "" echo "Or in your run command:"
echo " -v \"\${PWD:-.}/example:${ref}\"" echo ""
echo "" echo " -v \"\${PWD:-.}/example:${ref}\""
echo "Replace the example path ./example with your desired shared folder, which then will become visible here." echo ""
echo "" echo "Replace the example path ./example with your desired shared folder, which then will become visible here."
} | unix2dos > "$dir/readme.txt" echo ""
} | unix2dos > "$dir/readme.txt"; then
error "Failed to write shared folder readme!"
return 1
fi
return 0 return 0
} }
@@ -77,6 +82,7 @@ addShare() {
local comment="$4" local comment="$4"
local cfg="$5" local cfg="$5"
local owner="" local owner=""
local tmp="/tmp/smb"
if [ ! -d "$dir" ]; then if [ ! -d "$dir" ]; then
if ! mkdir -p "$dir"; then if ! mkdir -p "$dir"; then
@@ -85,13 +91,13 @@ addShare() {
fi fi
if ! ls -A "$dir" >/dev/null 2>&1; then if ! ls -A "$dir" >/dev/null 2>&1; then
msg="No permission to access shared folder ($dir)." local msg="No permission to access shared folder ($dir)."
msg+=" If SELinux is active, you need to add the \":Z\" flag to the bind mount." msg+=" If SELinux is active, you need to add the \":Z\" flag to the bind mount."
error "$msg" && return 1 error "$msg" && return 1
fi fi
if [ ! -w "$dir" ]; then if [ ! -w "$dir" ]; then
msg="shared folder ($dir) is not writeable!" local msg="shared folder ($dir) is not writeable!"
warn "$msg" warn "$msg"
fi fi
@@ -136,40 +142,50 @@ addShare() {
writeConfig() { writeConfig() {
{ echo "[global]" if ! {
echo " server string = Dockur" echo "[global]"
echo " netbios name = $hostname" echo " server string = Dockur"
echo " workgroup = WORKGROUP" echo " netbios name = $hostname"
echo " interfaces = $interfaces" echo " workgroup = WORKGROUP"
echo " bind interfaces only = yes" echo " interfaces = $interfaces"
echo " socket address = $socket" echo " bind interfaces only = yes"
echo " security = user" echo " security = user"
echo " guest account = nobody" echo " guest account = nobody"
echo " map to guest = Bad User" echo " map to guest = Bad User"
echo " server min protocol = NT1" echo " server min protocol = NT1"
echo " follow symlinks = yes" echo " follow symlinks = yes"
echo " wide links = yes" echo " wide links = yes"
echo " unix extensions = no" echo " unix extensions = no"
echo " inherit owner = yes" echo " inherit owner = yes"
echo " create mask = 0666" echo " create mask = 0666"
echo " directory mask = 02777" echo " directory mask = 02777"
echo " force user = root" echo " force user = root"
echo " force group = root" echo " force group = root"
echo " force create mode = 0666" echo " force create mode = 0666"
echo " force directory mode = 02777" echo " force directory mode = 02777"
echo "" echo ""
echo " # Disable printing services" echo " # Disable printing services"
echo " load printers = no" echo " load printers = no"
echo " printing = bsd" echo " printing = bsd"
echo " printcap name = /dev/null" echo " printcap name = /dev/null"
echo " disable spoolss = yes" echo " disable spoolss = yes"
} > "$SAMBA_CONFIG" } > "$SAMBA_CONFIG"; then
error "Failed to write Samba config \"$SAMBA_CONFIG\" !"
return 1
fi
return 0 return 0
} }
selectPrimaryShare() { selectPrimaryShare() {
local tmp="/tmp/smb"
if ! rm -rf "$tmp"; then
error "Failed to clean temporary Samba folder!"
return 1
fi
share="/shared" share="/shared"
[ ! -d "$share" ] && [ -d "$STORAGE/shared" ] && share="$STORAGE/shared" [ ! -d "$share" ] && [ -d "$STORAGE/shared" ] && share="$STORAGE/shared"
[ ! -d "$share" ] && [ -d "/data" ] && share="/data" [ ! -d "$share" ] && [ -d "/data" ] && share="/data"
@@ -227,7 +243,7 @@ startDaemon() {
local log="$2" local log="$2"
shift 2 shift 2
rm -f "$log" rm -f "$log" || :
if ! "$@"; then if ! "$@"; then
SAMBA_DEBUG="Y" SAMBA_DEBUG="Y"
@@ -269,30 +285,29 @@ startWsddn() {
return 0 return 0
} }
configureNetwork configureNetwork || return 0
html "Initializing shared folder..." html "Initializing shared folder..."
SAMBA_CONFIG="/etc/samba/smb.conf"
enabled "$DEBUG" && echo "Starting Samba daemon..." enabled "$DEBUG" && echo "Starting Samba daemon..."
writeConfig || return 1 writeConfig || return 0
# Add shared folders # Add shared folders
selectPrimaryShare selectPrimaryShare || return 0
! addShare "$share" "/shared" "Data" "Shared" "$SAMBA_CONFIG" && return 0
addOptionalShare "2" addShare "$share" "/shared" "Data" "Shared" "$SAMBA_CONFIG" || return 0
addOptionalShare "3" addOptionalShare "2" || :
addOptionalShare "3" || :
prepareSambaDirs || return 1 prepareSambaDirs || return 0
startSamba
startSamba || return 0
isUserMode && return 0 isUserMode && return 0
if [[ "${BOOT_MODE:-}" == "windows_legacy" ]]; then if [[ "${BOOT_MODE:-}" == "windows_legacy" ]]; then
startNetbios startNetbios || :
else else
startWsddn startWsddn || :
fi fi
return 0 return 0