packages/net/netatalk/files/afpd.init

201 lines
7.6 KiB
Bash

#!/bin/sh /etc/rc.common
# Copyright (C) 2010-2025 OpenWrt.org
START=85
STOP=10
USE_PROCD=1
PROG_afpd='/usr/sbin/afpd'
PROG_cnid='/usr/sbin/cnid_metad'
# Default config file location
config_file='/etc/afp.conf'
# Config file contents and status
afpd_config=''
config_overwrite=''
config_error=0
setup_error=0
# Log tag
log_tag='afpd-init'
# Configuration dictionary
valid_global='|'
valid_global=$valid_global'ad_domain|admin_auth_user|admin_group|force_user|force_group|k5_keytab|k5_service|k5_realm|'
valid_global=$valid_global'nt_domain|nt_separator|save_password|set_password|uam_list|uam_path|mac_charset|unix_charset|'
valid_global=$valid_global'vol_charset|passwd_file|passwd_minlen|afp_interfaces|afp_listen|afp_port|appletalk|'
valid_global=$valid_global'cnid_listen|cnid_server|ddp_address|ddp_zone|disconnect_time|dsireadbuf|hostname|'
valid_global=$valid_global'max_connections|sleep_time|chmod_request|dircachesize|extmap_file|'
valid_global=$valid_global'force_xattr_with_sticky_bit|guest_account|ignored_attributes|legacy_icon|login_message|'
valid_global=$valid_global'mimic_model|vol_dbpath|zeroconf_name|log_file|log_level|map_acls|ldap_auth_method|'
valid_global=$valid_global'ldap_auth_dn|ldap_auth_pw|ldap_uri|ldap_userbase|ldap_userscope|ldap_groupbase|'
valid_global=$valid_global'ldap_groupscope|ldap_uuid_attr|ldap_name_attr|ldap_group_attr|ldap_uuid_string|'
valid_global=$valid_global'ldap_uuid_encoding|ldap_user_filter|ldap_group_filter|vol_dbnest|fce_ignore_names|'
valid_homes='|basedir_regex|path|home_name|'
valid_volume='|'
valid_volume=$valid_volume'mac_charset|unix_charset|vol_charset|casefold|chmod_request|force_xattr_with_sticky_bit|'
valid_volume=$valid_volume'ignored_attributes|login_message|vol_dbpath|path|server_name|vol_size_limit|valid_users|'
valid_volume=$valid_volume'invalid_users|hosts_allow|hosts_deny|ea|password|file_perm|directory_perm|umask|preexec|'
valid_volume=$valid_volume'postexec|root_preexec|root_postexec|rolist|rwlist|veto_files|acls|case_sensitive|prodos|'
valid_volume=$valid_volume'read_only|time_machine|vol_dbnest|cnid_scheme|volume_name|'
valid_share='share_name'
NL=$'\n'
generate_config() {
# Save name of sections
config_name=''
global_name=''
homes_name=''
volume_names=''
# Volume name validation
share_names=''
fixed_names=''
# Call-back per section
config_cb() {
section_type="$1"
section_name="$2"
# Call-back per option
option_cb() {
local name="$1"
local value="$2"
# Validate options against dictionary of possible values
if [ "$section_type" = 'setup' -a "$CONFIG_SECTION" = "$config_name" ]; then
if [ "$name" = 'config_overwrite' ]; then
if [ "$value" = "0" -o "$value" = "1" ]; then
config_overwrite=$value
else
# Garbage on this option means we should not proceed no matter what
logger -p err -t $log_tag "Invalid SETUP config_overwrite option: $value"
setup_error=1
fi
elif [ "$name" = 'config_file' ]; then
config_file="$value"
else
config_error=1 && logger -p err -t $log_tag "Invalid SETUP configuration option: $name:$value"
fi
elif [ "$section_type" = 'global' -a "$CONFIG_SECTION" = "$global_name" ]; then
case "$valid_global" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid GLOBAL configuration option: $name:$value" ;;
esac
elif [ "$section_type" = 'homes' -a "$CONFIG_SECTION" = "$homes_name" ]; then
case "$valid_homes" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid HOMES configuration option: $name:$value" ;;
esac
elif [ "$section_type" = 'volume' ]; then
if [ "$name" = "$valid_share" ]; then
# Special case - share name... check for duplicates... track changes... fix heading.
case "||$share_names" in
*'||'$value'||'*) config_error=1 && logger -p err -t $log_tag "Duplicated share name $CONFIG_SECTION-$name:$value" ;;
*) ;;
esac
share_names=$share_names"$value||"
fixed_names=$fixed_names"$CONFIG_SECTION "
afpd_config="${afpd_config//\[\[$CONFIG_SECTION\]\]/[$value]}"
else
case "$valid_volume" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid VOLUME $CONFIG_SECTION configuration option: $name:$value" ;;
esac
fi
else
config_error=1 && logger -p err -t $log_tag "Invalid option. Section: $CONFIG_SECTION ($section_type), option: $name:$value"
fi
}
# Call-back per list - error, we don't use lists
list_cb() {
config_error=1 && logger -p err -t $log_tag "Invalid list in $CONFIG_SECTION: $1:$2"
}
# Identify sections and create section headers (placeholder for volumes)
if [ "$section_type" = 'setup' ]; then
# Find the name of the first (and only?) setup (control) section
if [ -z "$config_name" ]; then
config_name=$section_name
else
config_error=1 && logger -p err -t $log_tag 'Multiple SETUP sections defined'
fi
elif [ "$section_type" = 'global' ]; then
# Find the name of the first (and only?) global section
if [ -z "$global_name" ]; then
global_name=$section_name
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[Global]$NL"
else
config_error=1 && logger -p err -t $log_tag 'Multiple GLOBAL sections defined'
fi
elif [ "$section_type" = 'homes' ]; then
# Find the name of the first (and only?) homes section
if [ -z "$homes_name" ]; then
homes_name=$section_name
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[Homes]$NL"
else
config_error=1 && logger -p err -t $log_tag 'Multiple HOMES sections defined'
fi
elif [ "$section_type" = 'volume' ]; then
# Collect the names of the volume sections
volume_names=$volume_names"$section_name "
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[[$section_name]]$NL"
elif [ "$section_type" != '' ]; then
# It's not the end of file
config_error=1 && logger -p err -t $log_tag "Invalid $section_type section defined"
fi
}
# Load config (trigger callbacks)
config_load afpd
# config_overwrite is messed up... don't know what to do
if [ "$setup_error" -eq 1 ]; then
exit 1
fi
# So, should we? Shouldn't? Nobody said but gave us share details.
[ -z "$config_overwrite" ] && [ -n "$volume_names" -o -n "$homes_name" ] && {
logger -p warn -t $log_tag "No valid config_overwrite at SETUP config. Ignoring defined VOLUMES and/or HOMES"
}
# Only update configuration file if UCI config asks for it
build_config=$(expr "${config_overwrite}" == "1")
if [ "$build_config" -eq 1 ]; then
# One last check for valid volume names
[ "$volume_names" = "$fixed_names" ] || {
config_error=1 && logger -p err -t $log_tag "Not all volumes have valid option $valid_share"
}
# Continue only if configuration was decent - any errors were logged already
if [ "$config_error" -eq 1 ]; then
exit 1
fi
# Create file
mkdir -p `dirname "$config_file"`
echo "$afpd_config" > "$config_file"
logger -p info -t $log_tag "Configuration written to $config_file"
else
logger -p info -t $log_tag 'Configuration not modified - setup:config_overwrite=0 or missing'
fi
}
start_service() {
mkdir -p /var/netatalk/CNID/
generate_config
# afpd
procd_open_instance
procd_set_param command $PROG_afpd -d -F $config_file
procd_set_param file $config_file
procd_set_param respawn
procd_close_instance
# cnid
procd_open_instance
procd_set_param command $PROG_cnid -d -F $config_file
procd_set_param respawn
procd_close_instance
}