You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

357 lines
10 KiB

#!/bin/sh
# Enhanced MacOS installation script for zapret
# This script provides improved MacOS support with automatic architecture detection
EXEDIR="$(dirname "$0")"
EXEDIR="$(cd "$EXEDIR"; pwd)"
ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"}
ZAPRET_TARGET=${ZAPRET_TARGET:-/opt/zapret}
ZAPRET_TARGET_RW=${ZAPRET_RW:-"$ZAPRET_TARGET"}
ZAPRET_TARGET_CONFIG="$ZAPRET_TARGET_RW/config"
ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
local color="$1"
local message="$2"
printf "${color}${message}${NC}\n"
}
# Function to check if we're on MacOS
check_macos() {
if [ "$(uname)" != "Darwin" ]; then
print_status $RED "Error: This script is designed for MacOS only"
print_status $RED "Current system: $(uname)"
exit 1
fi
print_status $GREEN "✅ MacOS detected: $(uname -m)"
}
# Function to detect MacOS architecture
detect_architecture() {
local arch=$(uname -m)
case "$arch" in
x86_64)
echo "x86_64"
;;
arm64)
echo "arm64"
;;
*)
echo "unknown"
;;
esac
}
# Function to detect MacOS version
detect_version() {
if command -v sw_vers >/dev/null 2>&1; then
sw_vers -productVersion 2>/dev/null | cut -d. -f1,2
else
echo "10.8"
fi
}
# Function to check build tools
check_build_tools() {
print_status $BLUE "Checking build tools..."
local missing_tools=""
if ! command -v make >/dev/null 2>&1; then
missing_tools="$missing_tools make"
fi
if ! command -v cc >/dev/null 2>&1 && ! command -v clang >/dev/null 2>&1; then
missing_tools="$missing_tools compiler(cc/clang)"
fi
if ! command -v lipo >/dev/null 2>&1; then
missing_tools="$missing_tools lipo"
fi
if [ -n "$missing_tools" ]; then
print_status $RED "❌ Missing required tools: $missing_tools"
print_status $YELLOW "Installing Xcode Command Line Tools..."
xcode-select --install
print_status $YELLOW "Please complete the installation and run this script again"
exit 1
fi
print_status $GREEN "✅ All required build tools are available"
}
# Function to show system information
show_system_info() {
print_status $BLUE "System Information:"
echo "========================"
echo "System: $(uname)"
echo "Architecture: $(detect_architecture)"
echo "MacOS Version: $(detect_version)"
echo "Target: $(detect_architecture)-apple-macos$(detect_version)"
echo "Compiler: $(which cc 2>/dev/null || which clang 2>/dev/null)"
echo "Make: $(which make)"
echo "Lipo: $(which lipo)"
echo ""
}
# Function to build zapret
build_zapret() {
local arch=$(detect_architecture)
local version=$(detect_version)
print_status $BLUE "Building zapret for MacOS..."
echo "Architecture: $arch"
echo "Version: $version"
echo ""
# Set environment variables
export MACOS_TARGET="$(detect_architecture)-apple-macos$(detect_version)"
export MACOS_VERSION="$version"
# Build for current architecture
print_status $YELLOW "Building for current architecture..."
if make mac; then
print_status $GREEN "✅ Build completed successfully"
else
print_status $RED "❌ Build failed"
exit 1
fi
}
# Function to build universal binary
build_universal() {
local version=$(detect_version)
print_status $BLUE "Building universal binary for MacOS..."
echo "Version: $version"
echo ""
# Set environment variables
export MACOS_VERSION="$version"
# Build universal binary
print_status $YELLOW "Building universal binary (x86_64 + arm64)..."
if make mac-universal; then
print_status $GREEN "✅ Universal binary build completed successfully"
else
print_status $RED "❌ Universal binary build failed"
exit 1
fi
}
# Function to install binaries
install_binaries() {
print_status $BLUE "Installing binaries..."
# Check if binaries were built
if [ ! -d "$EXEDIR/binaries/my" ]; then
print_status $RED "❌ Binaries not found. Please build first."
exit 1
fi
# Create target directory
if [ ! -d "$ZAPRET_TARGET" ]; then
print_status $YELLOW "Creating target directory: $ZAPRET_TARGET"
sudo mkdir -p "$ZAPRET_TARGET"
fi
# Copy binaries
print_status $YELLOW "Copying binaries to $ZAPRET_TARGET..."
sudo cp -r "$EXEDIR/binaries/my"/* "$ZAPRET_TARGET/"
# Set permissions
print_status $YELLOW "Setting permissions..."
sudo chown -R root:wheel "$ZAPRET_TARGET"
sudo chmod -R 755 "$ZAPRET_TARGET"
print_status $GREEN "✅ Binaries installed successfully"
}
# Function to install configuration
install_config() {
print_status $BLUE "Installing configuration..."
# Create config directory
if [ ! -d "$(dirname "$ZAPRET_TARGET_CONFIG")" ]; then
sudo mkdir -p "$(dirname "$ZAPRET_TARGET_CONFIG")"
fi
# Copy default config if not exists
if [ ! -f "$ZAPRET_TARGET_CONFIG" ]; then
print_status $YELLOW "Installing default configuration..."
sudo cp "$ZAPRET_CONFIG_DEFAULT" "$ZAPRET_TARGET_CONFIG"
sudo chown root:wheel "$ZAPRET_TARGET_CONFIG"
sudo chmod 644 "$ZAPRET_TARGET_CONFIG"
else
print_status $YELLOW "Configuration already exists, skipping..."
fi
print_status $GREEN "✅ Configuration installed successfully"
}
# Function to install init scripts
install_init_scripts() {
print_status $BLUE "Installing init scripts..."
# Copy init scripts
if [ -d "$EXEDIR/init.d/macos" ]; then
print_status $YELLOW "Installing MacOS init scripts..."
sudo cp -r "$EXEDIR/init.d/macos" "$ZAPRET_TARGET/init.d/"
sudo chown -R root:wheel "$ZAPRET_TARGET/init.d/macos"
sudo chmod -R 755 "$ZAPRET_TARGET/init.d/macos"
fi
# Copy launchd plist
if [ -f "$EXEDIR/init.d/macos/zapret.plist" ]; then
print_status $YELLOW "Installing launchd plist..."
sudo cp "$EXEDIR/init.d/macos/zapret.plist" "/Library/LaunchDaemons/"
sudo chown root:wheel "/Library/LaunchDaemons/zapret.plist"
sudo chmod 644 "/Library/LaunchDaemons/zapret.plist"
fi
print_status $GREEN "✅ Init scripts installed successfully"
}
# Function to install documentation
install_docs() {
print_status $BLUE "Installing documentation..."
# Copy documentation
if [ -d "$EXEDIR/docs" ]; then
sudo cp -r "$EXEDIR/docs" "$ZAPRET_TARGET/"
sudo chown -R root:wheel "$ZAPRET_TARGET/docs"
sudo chmod -R 644 "$ZAPRET_TARGET/docs"
sudo find "$ZAPRET_TARGET/docs" -type d -exec chmod 755 {} \;
fi
print_status $GREEN "✅ Documentation installed successfully"
}
# Function to create symbolic links
create_symlinks() {
print_status $BLUE "Creating symbolic links..."
# Create symlinks in /usr/local/bin
if [ ! -d "/usr/local/bin" ]; then
sudo mkdir -p "/usr/local/bin"
fi
for binary in tpws ip2net mdig; do
if [ -f "$ZAPRET_TARGET/$binary" ]; then
print_status $YELLOW "Creating symlink for $binary..."
sudo ln -sf "$ZAPRET_TARGET/$binary" "/usr/local/bin/$binary"
fi
done
print_status $GREEN "✅ Symbolic links created successfully"
}
# Function to show post-installation information
show_post_install_info() {
print_status $GREEN "🎉 Installation completed successfully!"
echo ""
print_status $BLUE "Post-installation information:"
echo "================================"
echo "Installation directory: $ZAPRET_TARGET"
echo "Configuration file: $ZAPRET_TARGET_CONFIG"
echo "Control script: $ZAPRET_TARGET/init.d/macos/zapret"
echo ""
echo "Available commands:"
echo " tpws --help # Show tpws help"
echo " ip2net --help # Show ip2net help"
echo " mdig --help # Show mdig help"
echo ""
echo "Service management:"
echo " sudo $ZAPRET_TARGET/init.d/macos/zapret start # Start service"
echo " sudo $ZAPRET_TARGET/init.d/macos/zapret stop # Stop service"
echo " sudo $ZAPRET_TARGET/init.d/macos/zapret status # Show status"
echo ""
echo "Documentation:"
echo " $ZAPRET_TARGET/docs/README_MACOS_REFACTORING.md"
echo " $ZAPRET_TARGET/docs/bsd.en.md"
echo ""
print_status $YELLOW "Note: nfq component is not fully supported on MacOS"
print_status $YELLOW " Use tpws for DPI bypass functionality"
}
# Function to show help
show_help() {
echo "Usage: $0 [OPTION]"
echo ""
echo "Options:"
echo " build Build for current architecture (default)"
echo " universal Build universal binary (x86_64 + arm64)"
echo " install Install built binaries and configuration"
echo " full Build and install everything"
echo " info Show system information"
echo " help Show this help message"
echo ""
echo "Examples:"
echo " $0 build # Build for current architecture"
echo " $0 universal # Build universal binary"
echo " $0 install # Install built binaries"
echo " $0 full # Build and install everything"
}
# Main script logic
main() {
# Check if we're on MacOS
check_macos
# Show system information
show_system_info
# Check build tools
check_build_tools
case "${1:-build}" in
build)
build_zapret
;;
universal)
build_universal
;;
install)
install_binaries
install_config
install_init_scripts
install_docs
create_symlinks
show_post_install_info
;;
full)
build_zapret
install_binaries
install_config
install_init_scripts
install_docs
create_symlinks
show_post_install_info
;;
info)
# Already shown above
;;
help|--help|-h)
show_help
;;
*)
echo "Unknown option: $1"
echo "Use '$0 help' for usage information"
exit 1
;;
esac
}
# Run main function
main "$@"