Files
mars-nwe/tests/linux/afp_smoke_suite.sh
2026-05-30 22:35:35 +02:00

788 lines
31 KiB
Bash
Executable File

#!/usr/bin/env bash
# Run the mars_nwe AFP Linux smoke helpers as one collectable report.
#
# The helper intentionally keeps the password out of the printed command lines,
# captures AFP server diagnostics from the mars_nwe log while the probes run, and
# appends Linux xattr checks for the tested Unix file.
set -u
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
SERVER="MARS"
USER_NAME="SUPERVISOR"
PASSWORD=""
NETWARE_PATH="SYS:PUBLIC/pmdflts.ini"
UNIX_PATH="/var/mars_nwe/SYS/public/pmdflts.ini"
LOG_FILE="/var/log/mars_nwe/nw.log"
OUT_FILE=""
FINDER_TYPE="TEXT"
FINDER_CREATOR="MARS"
TIMESTAMP_EPOCH="1700000000"
CREATE_DIR_NAME=""
CREATE_FILE_NAME=""
READONLY_USER=""
READONLY_PASSWORD=""
READONLY_NO_PASSWORD=0
PREPARE_READONLY_RIGHTS=0
READONLY_RIGHTS="[RF]"
KEEP_GOING=1
CAPTURE_LOG=1
LOG_WINDOW_SECONDS=120
RENAME_DIR_NAME=""
RENAME_FILE_NAME=""
usage() {
cat <<USAGE
Usage: $0 -S SERVER -U USER -P PASSWORD [options]
Options:
--path NETWARE_PATH NetWare path to test (default: $NETWARE_PATH)
--unix-path UNIX_PATH Unix path for getfattr checks (default: $UNIX_PATH)
--log LOGFILE mars_nwe log to tail for AFP lines (default: $LOG_FILE)
--out FILE Write the complete report to FILE as well as stdout
--type FOURCC FinderInfo type written by Set File Info (default: $FINDER_TYPE)
--creator FOURCC FinderInfo creator written by Set File Info (default: $FINDER_CREATOR)
--mtime-epoch SECONDS AFP modify/backup timestamp to write (default: $TIMESTAMP_EPOCH)
--create-dir-name NAME Temporary directory name for AFP Create Directory (default: generated aHHMMSS)
--create-file-name NAME Temporary file name for AFP Create File (default: generated fHHMMR)
--rename-dir-name NAME Temporary directory name for AFP Rename (default: generated dHHMMR)
--rename-file-name NAME Temporary file name for AFP Rename (default: generated mHHMMR)
--readonly-user USER Optional user expected to lack Modify rights
--readonly-password PASS Password for --readonly-user
--readonly-no-password Use ncpfs -n for --readonly-user
--prepare-readonly-rights Prepare/revoke explicit rights around the negative test
--readonly-rights RIGHTS Rights granted by --prepare-readonly-rights (default: $READONLY_RIGHTS)
--log-window-seconds N Include only recent AFP log lines from the last N seconds (default: $LOG_WINDOW_SECONDS)
--no-log Do not tail/grep the server log
--stop-on-failure Stop after the first failing smoke command
-h, --help Show this help
The script expects the compiled smoke helpers in the same directory as this
script. It prints commands with the password masked, writes an AFP-only log
snippet, and runs getfattr checks for mars_nwe AFP xattrs.
USAGE
}
while [ $# -gt 0 ]; do
case "$1" in
-S|--server)
SERVER=$2; shift 2 ;;
-U|--user)
USER_NAME=$2; shift 2 ;;
-P|--password)
PASSWORD=$2; shift 2 ;;
--path)
NETWARE_PATH=$2; shift 2 ;;
--unix-path)
UNIX_PATH=$2; shift 2 ;;
--log)
LOG_FILE=$2; shift 2 ;;
--out)
OUT_FILE=$2; shift 2 ;;
--type)
FINDER_TYPE=$2; shift 2 ;;
--creator)
FINDER_CREATOR=$2; shift 2 ;;
--mtime-epoch)
TIMESTAMP_EPOCH=$2; shift 2 ;;
--create-dir-name)
CREATE_DIR_NAME=$2; shift 2 ;;
--create-file-name)
CREATE_FILE_NAME=$2; shift 2 ;;
--rename-dir-name)
RENAME_DIR_NAME=$2; shift 2 ;;
--rename-file-name)
RENAME_FILE_NAME=$2; shift 2 ;;
--readonly-user)
READONLY_USER=$2; shift 2 ;;
--readonly-password)
READONLY_PASSWORD=$2; READONLY_NO_PASSWORD=0; shift 2 ;;
--readonly-no-password)
READONLY_PASSWORD=""; READONLY_NO_PASSWORD=1; shift ;;
--prepare-readonly-rights)
PREPARE_READONLY_RIGHTS=1; shift ;;
--readonly-rights)
READONLY_RIGHTS=$2; shift 2 ;;
--log-window-seconds)
LOG_WINDOW_SECONDS=$2; shift 2 ;;
--no-log)
CAPTURE_LOG=0; shift ;;
--stop-on-failure)
KEEP_GOING=0; shift ;;
-h|--help)
usage; exit 0 ;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2 ;;
esac
done
if [ -z "$PASSWORD" ]; then
echo "Missing password. Use -P PASSWORD." >&2
usage >&2
exit 2
fi
case "$FINDER_TYPE" in
???? ) ;;
*) echo "--type must be exactly four characters" >&2; exit 2 ;;
esac
case "$FINDER_CREATOR" in
???? ) ;;
*) echo "--creator must be exactly four characters" >&2; exit 2 ;;
esac
case "$CREATE_DIR_NAME" in
""|*/*|*\\*|*:*) echo "--create-dir-name must be a single path component" >&2; exit 2 ;;
esac
case "$CREATE_FILE_NAME" in
""|*/*|*\\*|*:*) echo "--create-file-name must be a single path component" >&2; exit 2 ;;
esac
case "$LOG_WINDOW_SECONDS" in
''|*[!0-9]*) echo "--log-window-seconds must be a positive integer" >&2; exit 2 ;;
esac
if [ "$LOG_WINDOW_SECONDS" -le 0 ]; then
echo "--log-window-seconds must be greater than zero" >&2
exit 2
fi
if [ -z "$CREATE_DIR_NAME" ]; then
CREATE_DIR_NAME=$(date +a%H%M%S)
fi
if [ -z "$CREATE_FILE_NAME" ]; then
CREATE_FILE_NAME=$(printf 'f%04d%01d' "$((10#$(date +%H%M) % 10000))" "$((RANDOM % 10))")
fi
if [ -z "$RENAME_DIR_NAME" ]; then
RENAME_DIR_NAME=$(printf 'd%04d%01d' "$((10#$(date +%H%M) % 10000))" "$((RANDOM % 10))")
fi
if [ -z "$RENAME_FILE_NAME" ]; then
RENAME_FILE_NAME=$(printf 'm%04d%01d' "$((10#$(date +%H%M) % 10000))" "$((RANDOM % 10))")
fi
case "$CREATE_DIR_NAME" in
???????|??????|?????|????|???|??|?) ;;
*) echo "--create-dir-name must be at most seven characters so the AFP 2.0 companion name stays DOS-compatible" >&2; exit 2 ;;
esac
case "$CREATE_FILE_NAME" in
???????|??????|?????|????|???|??|?) ;;
*) echo "--create-file-name must be at most seven characters so the AFP 2.0 companion name stays DOS-compatible" >&2; exit 2 ;;
esac
case "$RENAME_DIR_NAME" in
???????|??????|?????|????|???|??|?) ;;
*) echo "--rename-dir-name must be at most seven characters" >&2; exit 2 ;;
esac
case "$RENAME_FILE_NAME" in
???????|??????|?????|????|???|??|?) ;;
*) echo "--rename-file-name must be at most seven characters" >&2; exit 2 ;;
esac
DIR_PATH=$NETWARE_PATH
case "$NETWARE_PATH" in
*/*) DIR_PATH=${NETWARE_PATH%/*} ;;
esac
CREATE_DIR_PATH="$DIR_PATH/$CREATE_DIR_NAME"
CREATE_DIR20_PATH="$DIR_PATH/${CREATE_DIR_NAME}2"
UNIX_PARENT_PATH=$(dirname -- "$UNIX_PATH")
CREATE_DIR_NAME_DOS=$(printf '%s' "$CREATE_DIR_NAME" | tr '[:lower:]' '[:upper:]')
CREATE_DIR20_NAME_DOS=$(printf '%s' "${CREATE_DIR_NAME}2" | tr '[:lower:]' '[:upper:]')
UNIX_DIR_PATH=$UNIX_PARENT_PATH/$CREATE_DIR_NAME
UNIX_DIR20_PATH=$UNIX_PARENT_PATH/${CREATE_DIR_NAME}2
UNIX_DIR_PATH_DOS=$UNIX_PARENT_PATH/$CREATE_DIR_NAME_DOS
UNIX_DIR20_PATH_DOS=$UNIX_PARENT_PATH/$CREATE_DIR20_NAME_DOS
CREATE_FILE_PATH="$DIR_PATH/$CREATE_FILE_NAME"
CREATE_FILE20_PATH="$DIR_PATH/${CREATE_FILE_NAME}2"
CREATE_FILE_NAME_DOS=$(printf '%s' "$CREATE_FILE_NAME" | tr '[:lower:]' '[:upper:]')
CREATE_FILE20_NAME_DOS=$(printf '%s' "${CREATE_FILE_NAME}2" | tr '[:lower:]' '[:upper:]')
UNIX_FILE_PATH=$UNIX_PARENT_PATH/$CREATE_FILE_NAME
UNIX_FILE20_PATH=$UNIX_PARENT_PATH/${CREATE_FILE_NAME}2
UNIX_FILE_PATH_DOS=$UNIX_PARENT_PATH/$CREATE_FILE_NAME_DOS
UNIX_FILE20_PATH_DOS=$UNIX_PARENT_PATH/$CREATE_FILE20_NAME_DOS
RENAME_DIR_FROM_PATH="$DIR_PATH/$RENAME_DIR_NAME"
RENAME_DIR_TO_PATH="$DIR_PATH/${RENAME_DIR_NAME}r"
RENAME_FILE_FROM_PATH="$DIR_PATH/$RENAME_FILE_NAME"
RENAME_FILE_TO_PATH="$DIR_PATH/${RENAME_FILE_NAME}r"
REPORT_TMP=$(mktemp "${TMPDIR:-/tmp}/mars-afp-smoke.XXXXXX")
LOG_TMP=$(mktemp "${TMPDIR:-/tmp}/mars-afp-log.XXXXXX")
LOG_RECENT_TMP=$(mktemp "${TMPDIR:-/tmp}/mars-afp-log-recent.XXXXXX")
LOG_PID=""
FAILURES=0
RIGHTS_PREPARED=0
cleanup() {
if [ "$RIGHTS_PREPARED" -eq 1 ] && [ -n "$READONLY_USER" ]; then
nwrevoke -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
-o "$READONLY_USER" -t 1 "$NETWARE_PATH" >/dev/null 2>&1 || true
RIGHTS_PREPARED=0
fi
if [ -n "$LOG_PID" ] && kill -0 "$LOG_PID" 2>/dev/null; then
kill "$LOG_PID" 2>/dev/null || true
wait "$LOG_PID" 2>/dev/null || true
fi
rm -f "$LOG_TMP" "$LOG_RECENT_TMP"
}
trap cleanup EXIT INT TERM
emit() {
printf '%s\n' "$*" | tee -a "$REPORT_TMP"
}
section() {
emit ""
emit "## $*"
}
run_cmd() {
local label=$1
local printable=$2
shift 2
section "$label"
emit "\$ $printable"
"$@" 2>&1 | tee -a "$REPORT_TMP"
local status=${PIPESTATUS[0]}
emit "[exit=$status]"
if [ "$status" -ne 0 ]; then
FAILURES=$((FAILURES + 1))
if [ "$KEEP_GOING" -eq 0 ]; then
finish_report
exit "$status"
fi
fi
}
cleanup_created_dir() {
local path=$1
local dos_path=$2
if [ -d "$path" ]; then
rmdir "$path"
elif [ -d "$dos_path" ]; then
rmdir "$dos_path"
else
rmdir "$path"
fi
}
cleanup_created_file() {
local path=$1
local dos_path=$2
if [ -f "$path" ]; then
rm -f "$path"
elif [ -f "$dos_path" ]; then
rm -f "$dos_path"
else
rm -f "$path"
fi
}
run_optional_cmd() {
local label=$1
local printable=$2
shift 2
section "$label"
emit "\$ $printable"
"$@" 2>&1 | tee -a "$REPORT_TMP"
local status=${PIPESTATUS[0]}
emit "[exit=$status]"
return "$status"
}
readonly_print_auth() {
if [ "$READONLY_NO_PASSWORD" -eq 1 ]; then
printf '%s' "-n"
else
printf '%s' "-P ******"
fi
}
capture_recent_afp_log() {
local cutoff
: >"$LOG_RECENT_TMP"
if [ ! -r "$LOG_FILE" ]; then
return 1
fi
cutoff=$(date -d "@$(( $(date +%s) - LOG_WINDOW_SECONDS ))" '+%m.%d,%H:%M:%S' 2>/dev/null) || return 1
awk -v cutoff="$cutoff" '
/AFP/ {
ts = substr($0, 1, 14)
if (ts >= cutoff) print
}
' "$LOG_FILE" >"$LOG_RECENT_TMP"
}
finish_report() {
if [ "$CAPTURE_LOG" -eq 1 ]; then
sleep 1
if [ -n "$LOG_PID" ] && kill -0 "$LOG_PID" 2>/dev/null; then
kill "$LOG_PID" 2>/dev/null || true
wait "$LOG_PID" 2>/dev/null || true
LOG_PID=""
fi
section "AFP server log excerpt"
emit "recent_window_seconds=$LOG_WINDOW_SECONDS"
if capture_recent_afp_log && [ -s "$LOG_RECENT_TMP" ]; then
cat "$LOG_RECENT_TMP" | tee -a "$REPORT_TMP"
elif [ -s "$LOG_TMP" ]; then
cat "$LOG_TMP" | tee -a "$REPORT_TMP"
else
emit "No AFP lines captured from $LOG_FILE."
fi
fi
section "Summary"
emit "failures=$FAILURES"
if [ -n "$OUT_FILE" ]; then
cp "$REPORT_TMP" "$OUT_FILE"
emit "report=$OUT_FILE"
fi
}
section "mars_nwe AFP smoke suite"
emit "date=$(date -Is)"
emit "server=$SERVER"
emit "user=$USER_NAME"
emit "path=$NETWARE_PATH"
emit "dir_path=$DIR_PATH"
emit "unix_path=$UNIX_PATH"
emit "log=$LOG_FILE"
emit "log_window_seconds=$LOG_WINDOW_SECONDS"
emit "finder_type=$FINDER_TYPE"
emit "finder_creator=$FINDER_CREATOR"
emit "mtime_epoch=$TIMESTAMP_EPOCH"
emit "create_dir_path=$CREATE_DIR_PATH"
emit "create_dir20_path=$CREATE_DIR20_PATH"
emit "unix_dir_path=$UNIX_DIR_PATH"
emit "unix_dir20_path=$UNIX_DIR20_PATH"
emit "unix_dir_path_dos=$UNIX_DIR_PATH_DOS"
emit "unix_dir20_path_dos=$UNIX_DIR20_PATH_DOS"
emit "create_file_path=$CREATE_FILE_PATH"
emit "create_file20_path=$CREATE_FILE20_PATH"
emit "rename_dir_from_path=$RENAME_DIR_FROM_PATH"
emit "rename_dir_to_path=$RENAME_DIR_TO_PATH"
emit "rename_file_from_path=$RENAME_FILE_FROM_PATH"
emit "rename_file_to_path=$RENAME_FILE_TO_PATH"
emit "unix_file_path=$UNIX_FILE_PATH"
emit "unix_file20_path=$UNIX_FILE20_PATH"
emit "unix_file_path_dos=$UNIX_FILE_PATH_DOS"
emit "unix_file20_path_dos=$UNIX_FILE20_PATH_DOS"
if [ -n "$READONLY_USER" ]; then
emit "readonly_user=$READONLY_USER"
if [ "$READONLY_NO_PASSWORD" -eq 1 ]; then
emit "readonly_auth=no-password"
else
emit "readonly_auth=password"
fi
emit "prepare_readonly_rights=$PREPARE_READONLY_RIGHTS"
emit "readonly_rights=$READONLY_RIGHTS"
fi
for helper in \
afp_entry_id_smoke \
afp_file_info_smoke \
afp_dos_name_smoke \
afp_scan_info_smoke \
afp_create_directory_smoke \
afp_create_file_smoke \
afp_temp_dir_handle_smoke \
afp_open_file_fork_smoke \
afp_set_file_info_smoke
do
if [ ! -x "$SCRIPT_DIR/$helper" ]; then
emit "Missing executable: $SCRIPT_DIR/$helper"
exit 2
fi
done
if [ "$CAPTURE_LOG" -eq 1 ]; then
if [ -r "$LOG_FILE" ]; then
# Capture only lines appended while this script is running.
tail -n 0 -F "$LOG_FILE" 2>/dev/null | grep --line-buffered AFP >"$LOG_TMP" &
LOG_PID=$!
sleep 1
else
emit "Log file is not readable, disabling log capture: $LOG_FILE"
CAPTURE_LOG=0
fi
fi
COMMON_PRINT="-S $SERVER -U $USER_NAME -P ******"
if [ -n "$READONLY_USER" ] && [ "$PREPARE_READONLY_RIGHTS" -eq 1 ]; then
# Establish a conservative explicit trustee assignment for the negative
# metadata-write probes. The final nwrevoke below removes only this
# explicit assignment and returns the object to its inherited rights.
run_optional_cmd \
"Prepare readonly trustee cleanup" \
"nwrevoke -S $SERVER -U $USER_NAME -P ****** -o $READONLY_USER -t 1 '$NETWARE_PATH'" \
nwrevoke -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
-o "$READONLY_USER" -t 1 "$NETWARE_PATH" || true
run_cmd \
"Prepare readonly trustee rights" \
"nwgrant -S $SERVER -U $USER_NAME -P ****** -o $READONLY_USER -t 1 -r '$READONLY_RIGHTS' '$NETWARE_PATH'" \
nwgrant -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
-o "$READONLY_USER" -t 1 -r "$READONLY_RIGHTS" "$NETWARE_PATH"
RIGHTS_PREPARED=1
fi
run_cmd \
"AFP Entry ID From Path Name" \
"./afp_entry_id_smoke $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_entry_id_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Entry ID From NetWare Handle" \
"./afp_entry_id_smoke --from-handle $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_entry_id_smoke" --from-handle -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP 2.0 Get File Information" \
"./afp_file_info_smoke $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Get DOS Name From Entry ID" \
"./afp_dos_name_smoke $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_dos_name_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP 2.0 Scan File Information" \
"./afp_scan_info_smoke $COMMON_PRINT '$DIR_PATH'" \
"$SCRIPT_DIR/afp_scan_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$DIR_PATH"
run_cmd \
"AFP Alloc Temporary Directory Handle" \
"./afp_temp_dir_handle_smoke $COMMON_PRINT '$DIR_PATH'" \
"$SCRIPT_DIR/afp_temp_dir_handle_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$DIR_PATH"
if [ -d "$UNIX_DIR_PATH" ] || [ -d "$UNIX_DIR_PATH_DOS" ]; then
run_optional_cmd \
"Prepare AFP Create Directory cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_DIR_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR_PATH" || true
fi
if [ -d "$UNIX_DIR20_PATH" ] || [ -d "$UNIX_DIR20_PATH_DOS" ]; then
run_optional_cmd \
"Prepare AFP 2.0 Create Directory cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_DIR20_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR20_PATH" || true
fi
run_cmd \
"AFP Create Directory" \
"./afp_create_directory_smoke $COMMON_PRINT '$CREATE_DIR_PATH'" \
"$SCRIPT_DIR/afp_create_directory_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR_PATH"
run_cmd \
"AFP 2.0 Create Directory" \
"./afp_create_directory_smoke --afp20 $COMMON_PRINT '$CREATE_DIR20_PATH'" \
"$SCRIPT_DIR/afp_create_directory_smoke" --afp20 \
-S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR20_PATH"
run_cmd \
"AFP Delete Created Directory" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_DIR_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR_PATH"
run_cmd \
"AFP Delete Created 2.0 Directory" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_DIR20_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_DIR20_PATH"
if [ -f "$UNIX_FILE_PATH" ] || [ -f "$UNIX_FILE_PATH_DOS" ]; then
run_optional_cmd \
"Prepare AFP Create File cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_FILE_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE_PATH" || true
fi
if [ -f "$UNIX_FILE20_PATH" ] || [ -f "$UNIX_FILE20_PATH_DOS" ]; then
run_optional_cmd \
"Prepare AFP 2.0 Create File cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_FILE20_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE20_PATH" || true
fi
run_cmd \
"AFP Create File" \
"./afp_create_file_smoke $COMMON_PRINT '$CREATE_FILE_PATH'" \
"$SCRIPT_DIR/afp_create_file_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE_PATH"
run_cmd \
"AFP 2.0 Create File" \
"./afp_create_file_smoke --afp20 $COMMON_PRINT '$CREATE_FILE20_PATH'" \
"$SCRIPT_DIR/afp_create_file_smoke" --afp20 \
-S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE20_PATH"
run_cmd \
"AFP Delete Created File" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_FILE_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE_PATH"
run_cmd \
"AFP Delete Created 2.0 File" \
"./afp_delete_smoke $COMMON_PRINT '$CREATE_FILE20_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$CREATE_FILE20_PATH"
run_optional_cmd \
"Prepare AFP Rename Directory cleanup source" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_DIR_FROM_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_DIR_FROM_PATH" || true
run_optional_cmd \
"Prepare AFP Rename Directory cleanup destination" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_DIR_TO_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_DIR_TO_PATH" || true
run_cmd \
"AFP Rename Directory create source" \
"./afp_create_directory_smoke $COMMON_PRINT '$RENAME_DIR_FROM_PATH'" \
"$SCRIPT_DIR/afp_create_directory_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_DIR_FROM_PATH"
run_cmd \
"AFP Rename Directory" \
"./afp_rename_smoke $COMMON_PRINT '$RENAME_DIR_FROM_PATH' '$RENAME_DIR_TO_PATH'" \
"$SCRIPT_DIR/afp_rename_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_DIR_FROM_PATH" "$RENAME_DIR_TO_PATH"
run_cmd \
"AFP Rename Directory cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_DIR_TO_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_DIR_TO_PATH"
run_optional_cmd \
"Prepare AFP Rename File cleanup source" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_FILE_FROM_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_FILE_FROM_PATH" || true
run_optional_cmd \
"Prepare AFP Rename File cleanup destination" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_FILE_TO_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_FILE_TO_PATH" || true
run_cmd \
"AFP Rename File create source" \
"./afp_create_file_smoke $COMMON_PRINT '$RENAME_FILE_FROM_PATH'" \
"$SCRIPT_DIR/afp_create_file_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_FILE_FROM_PATH"
run_cmd \
"AFP Rename File" \
"./afp_rename_smoke $COMMON_PRINT '$RENAME_FILE_FROM_PATH' '$RENAME_FILE_TO_PATH'" \
"$SCRIPT_DIR/afp_rename_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_FILE_FROM_PATH" "$RENAME_FILE_TO_PATH"
run_cmd \
"AFP Rename File cleanup" \
"./afp_delete_smoke $COMMON_PRINT '$RENAME_FILE_TO_PATH'" \
"$SCRIPT_DIR/afp_delete_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$RENAME_FILE_TO_PATH"
run_cmd \
"AFP Open File Fork" \
"./afp_open_file_fork_smoke $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_open_file_fork_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Open File Fork write access rejected" \
"./afp_open_file_fork_smoke --expect-completion 0x84 --access 0x02 $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_open_file_fork_smoke" --expect-completion 0x84 --access 0x02 \
-S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Open File Fork resource fork rejected" \
"./afp_open_file_fork_smoke --expect-completion 0x9c --fork 1 $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_open_file_fork_smoke" --expect-completion 0x9c --fork 1 \
-S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information FinderInfo" \
"./afp_set_file_info_smoke $COMMON_PRINT --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information FinderInfo legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information FinderInfo WebSDK layout" \
"./afp_set_file_info_smoke $COMMON_PRINT --websdk-layout --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--websdk-layout --finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information FinderInfo WebSDK legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --websdk-layout --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --websdk-layout --finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Hidden WebSDK layout" \
"./afp_set_file_info_smoke $COMMON_PRINT --websdk-layout --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--websdk-layout --attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Hidden WebSDK layout" \
"./afp_set_file_info_smoke $COMMON_PRINT --websdk-layout --attributes-only --clear-hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--websdk-layout --attributes-only --clear-hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Hidden" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Hidden" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --clear-hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Hidden legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Hidden legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --clear-hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --attributes-only --clear-hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Access Timestamp" \
"./afp_set_file_info_smoke $COMMON_PRINT --access-time-only --access-time-epoch '$TIMESTAMP_EPOCH' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--access-time-only --access-time-epoch "$TIMESTAMP_EPOCH" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Create Timestamp" \
"./afp_set_file_info_smoke $COMMON_PRINT --create-time-only --create-time-epoch '$TIMESTAMP_EPOCH' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--create-time-only --create-time-epoch "$TIMESTAMP_EPOCH" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Modify Timestamp" \
"./afp_set_file_info_smoke $COMMON_PRINT --timestamp-only --mtime-epoch '$TIMESTAMP_EPOCH' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--timestamp-only --mtime-epoch "$TIMESTAMP_EPOCH" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Backup Timestamp" \
"./afp_set_file_info_smoke $COMMON_PRINT --backup-time-only --backup-time-epoch '$TIMESTAMP_EPOCH' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--backup-time-only --backup-time-epoch "$TIMESTAMP_EPOCH" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information System" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --system '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --system "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear System" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-system '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --clear-system "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Archive" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --archive '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --archive "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Archive" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-archive '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --clear-archive "$NETWARE_PATH"
if [ -n "$READONLY_USER" ]; then
READONLY_PRINT="-S $SERVER -U $READONLY_USER $(readonly_print_auth)"
if [ "$READONLY_NO_PASSWORD" -eq 1 ]; then
READONLY_AUTH_ARGS=(-n)
else
READONLY_AUTH_ARGS=(-P "$READONLY_PASSWORD")
fi
run_cmd \
"AFP Get File Information readonly rights" \
"./afp_file_info_smoke --expect-rights-set 0x0100 --expect-rights-clear 0x9200 $READONLY_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_file_info_smoke" --expect-rights-set 0x0100 --expect-rights-clear 0x9200 \
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" "$NETWARE_PATH"
run_cmd \
"AFP metadata Modify rights rejected: FinderInfo" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" --expect-completion 0x8c \
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" \
--finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP attribute Modify rights rejected: Hidden" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" --expect-completion 0x8c \
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" \
--attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP metadata Modify rights rejected: System" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --attributes-only --system '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" --expect-completion 0x8c \
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" \
--attributes-only --system "$NETWARE_PATH"
fi
if [ -n "$READONLY_USER" ] && [ "$PREPARE_READONLY_RIGHTS" -eq 1 ]; then
run_cmd \
"Restore readonly trustee assignment" \
"nwrevoke -S $SERVER -U $USER_NAME -P ****** -o $READONLY_USER -t 1 '$NETWARE_PATH'" \
nwrevoke -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
-o "$READONLY_USER" -t 1 "$NETWARE_PATH"
RIGHTS_PREPARED=0
fi
if command -v stat >/dev/null 2>&1; then
run_cmd \
"Linux stat: AFP Modify Timestamp" \
"stat -c 'mtime_epoch=%Y mtime=%y' '$UNIX_PATH'" \
stat -c 'mtime_epoch=%Y mtime=%y' "$UNIX_PATH"
fi
if command -v getfattr >/dev/null 2>&1; then
run_cmd \
"Linux xattr: AFP FinderInfo" \
"getfattr -n user.org.mars-nwe.afp.finder-info -e hex '$UNIX_PATH'" \
getfattr -n user.org.mars-nwe.afp.finder-info -e hex "$UNIX_PATH"
run_optional_cmd \
"Linux xattr: AFP Attributes (optional AFP-only bits)" \
"getfattr -n user.org.mars-nwe.afp.attributes -e hex '$UNIX_PATH'" \
getfattr -n user.org.mars-nwe.afp.attributes -e hex "$UNIX_PATH" || \
emit "AFP-only attributes xattr is absent; this is expected when the tested Hidden/System/Archive bits are stored through the NetWare attribute path."
run_cmd \
"Linux xattr: NetWare FileInfo metadata" \
"getfattr -n user.org.mars-nwe.netware.fileinfo -e hex '$UNIX_PATH'" \
getfattr -n user.org.mars-nwe.netware.fileinfo -e hex "$UNIX_PATH"
run_cmd \
"Linux xattr: NetWare Archive metadata" \
"getfattr -n user.org.mars-nwe.netware.archive -e hex '$UNIX_PATH'" \
getfattr -n user.org.mars-nwe.netware.archive -e hex "$UNIX_PATH"
run_cmd \
"Linux xattr: AFP Entry ID" \
"getfattr -n user.org.mars-nwe.afp.entry-id -e hex '$UNIX_PATH'" \
getfattr -n user.org.mars-nwe.afp.entry-id -e hex "$UNIX_PATH"
else
section "Linux xattr checks"
emit "getfattr not found; install the attr package to collect xattr output."
FAILURES=$((FAILURES + 1))
fi
finish_report
if [ "$FAILURES" -ne 0 ]; then
exit 1
fi
exit 0