Copy QuecManager beta to non-beta
QM BETA --> regular/non-beta
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set content type to JSON
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Configuration
|
||||
QUEUE_DIR="/tmp/at_queue"
|
||||
RESULTS_DIR="$QUEUE_DIR/results"
|
||||
RESULT_FILE="/tmp/qscan_result.json"
|
||||
PID_FILE="/tmp/cell_scan.pid"
|
||||
TOKEN_FILE="$QUEUE_DIR/token"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level="${2:-info}"
|
||||
logger -t at_queue -p "daemon.$level" "check_scan: $1"
|
||||
}
|
||||
|
||||
# Function to output JSON response
|
||||
output_json() {
|
||||
local status="$1"
|
||||
local message="$2"
|
||||
|
||||
if [ "$status" = "success" ] && [ -f "$RESULT_FILE" ]; then
|
||||
# Return the contents of the result file
|
||||
cat "$RESULT_FILE"
|
||||
else
|
||||
printf '{"status":"%s","message":"%s","timestamp":"","output":""}\n' "$status" "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for scan token holder
|
||||
check_token_holder() {
|
||||
if [ -f "$TOKEN_FILE" ]; then
|
||||
local current_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id' 2>/dev/null)
|
||||
if [ -n "$current_holder" ] && echo "$current_holder" | grep -q "CELL_SCAN"; then
|
||||
log_message "Cell scan token is active: $current_holder" "debug"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if a scan is already in progress
|
||||
check_scan_progress() {
|
||||
# First check PID file
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_message "Scan in progress (PID: $pid)" "info"
|
||||
output_json "running" "Scan in progress"
|
||||
exit 0
|
||||
else
|
||||
log_message "Removing stale PID file" "warn"
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Also check token holder
|
||||
if check_token_holder; then
|
||||
log_message "Scan in progress (Token active)" "info"
|
||||
output_json "running" "Scan in progress (Token active)"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for existing results
|
||||
check_results() {
|
||||
if [ -f "$RESULT_FILE" ]; then
|
||||
rm -f "$RESULT_FILE" # Remove the result file if it exists
|
||||
log_message "Result file removed" "info"
|
||||
output_json "success" "Scan results removed"
|
||||
exit 0
|
||||
else
|
||||
log_message "No result file found to clear" "info"
|
||||
output_json "success" "No result file to clear"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
{
|
||||
# First check if a scan is in progress
|
||||
check_scan_progress
|
||||
|
||||
# Then check for existing results
|
||||
check_results
|
||||
|
||||
# If no results and no running scan, indicate idle state
|
||||
log_message "No active scan or recent results" "info"
|
||||
output_json "success" "No active scan"
|
||||
exit 0
|
||||
} || {
|
||||
# Error handler
|
||||
log_message "Failed to remove scan results" "error"
|
||||
output_json "error" "Failed to remove scan results"
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
# Simple script to fetch interpreted QCAINFO results
|
||||
|
||||
INTERPRETED_FILE="/tmp/interpreted_result.json"
|
||||
|
||||
# Set content type for JSON
|
||||
echo "Content-Type: application/json"
|
||||
echo "Access-Control-Allow-Origin: *"
|
||||
echo "Access-Control-Allow-Methods: GET, POST, OPTIONS"
|
||||
echo "Access-Control-Allow-Headers: Content-Type"
|
||||
echo ""
|
||||
|
||||
# Check if file exists
|
||||
if [ ! -f "$INTERPRETED_FILE" ]; then
|
||||
echo "[]"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Return the JSON content
|
||||
cat "$INTERPRETED_FILE"
|
||||
@@ -1,9 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Keep-Alive Scheduling Script
|
||||
# This script allows scheduling of keep-alive requests to prevent the connection from being closed.
|
||||
# It supports setting a time interval during which the keep-alive requests will be made.
|
||||
# It uses a worker script to perform the actual keep-alive requests by downloading a test file.
|
||||
|
||||
# Configuration
|
||||
CONFIG_FILE="/etc/keep_alive_schedule.conf"
|
||||
STATUS_FILE="/tmp/keep_alive_status"
|
||||
SPEEDTEST_SCRIPT="/www/cgi-bin/home/speedtest/speedtest.sh"
|
||||
KEEP_ALIVE_SCRIPT="/www/cgi-bin/quecmanager/experimental/keep_alive_worker.sh"
|
||||
TEST_URL="https://ash-speed.hetzner.com/100MB.bin"
|
||||
TEMP_FILE="/tmp/keep_alive_test.bin"
|
||||
|
||||
# Function to convert HH:MM to minutes since midnight
|
||||
time_to_minutes() {
|
||||
@@ -35,6 +42,49 @@ validate_interval() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to create the keep-alive worker script
|
||||
create_worker_script() {
|
||||
cat > "$KEEP_ALIVE_SCRIPT" << 'EOF'
|
||||
#!/bin/sh
|
||||
|
||||
TEST_URL="https://ash-speed.hetzner.com/100MB.bin"
|
||||
TEMP_FILE="/tmp/keep_alive_test.bin"
|
||||
|
||||
# Function to perform keep-alive test
|
||||
perform_keep_alive() {
|
||||
# Download the test file in background
|
||||
wget -q -O "$TEMP_FILE" "$TEST_URL" &
|
||||
WGET_PID=$!
|
||||
|
||||
# Wait for download to complete or timeout after 30 seconds
|
||||
COUNTER=0
|
||||
while [ $COUNTER -lt 30 ]; do
|
||||
if ! kill -0 $WGET_PID 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
COUNTER=$((COUNTER + 1))
|
||||
done
|
||||
|
||||
# If download is still running, kill it
|
||||
if kill -0 $WGET_PID 2>/dev/null; then
|
||||
kill $WGET_PID 2>/dev/null
|
||||
fi
|
||||
|
||||
# Wait 3 seconds then delete the file
|
||||
sleep 3
|
||||
#rm -f "$TEMP_FILE"
|
||||
|
||||
# Log the activity
|
||||
echo "$(date): Keep-alive test performed" >> /tmp/keep_alive.log
|
||||
}
|
||||
|
||||
# Execute the keep-alive test
|
||||
perform_keep_alive
|
||||
EOF
|
||||
chmod +x "$KEEP_ALIVE_SCRIPT"
|
||||
}
|
||||
|
||||
# Function to generate cron time expression
|
||||
generate_cron_time() {
|
||||
START_TIME=$1
|
||||
@@ -49,10 +99,10 @@ generate_cron_time() {
|
||||
# If end time is less than start time, it means we cross midnight
|
||||
if [ $(time_to_minutes "$END_TIME") -lt $(time_to_minutes "$START_TIME") ]; then
|
||||
# Create two cron entries for before and after midnight
|
||||
echo "*/$INTERVAL $START_HOUR-23 * * * $SPEEDTEST_SCRIPT"
|
||||
echo "*/$INTERVAL 0-$((END_HOUR - 1)) * * * $SPEEDTEST_SCRIPT"
|
||||
echo "*/$INTERVAL $START_HOUR-23 * * * $KEEP_ALIVE_SCRIPT"
|
||||
echo "*/$INTERVAL 0-$((END_HOUR - 1)) * * * $KEEP_ALIVE_SCRIPT"
|
||||
else
|
||||
echo "*/$INTERVAL $START_HOUR-$((END_HOUR - 1)) * * * $SPEEDTEST_SCRIPT"
|
||||
echo "*/$INTERVAL $START_HOUR-$((END_HOUR - 1)) * * * $KEEP_ALIVE_SCRIPT"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -75,7 +125,10 @@ disable_scheduling() {
|
||||
sed -i 's/ENABLED=1/ENABLED=0/' "$CONFIG_FILE"
|
||||
fi
|
||||
# Remove any existing cron jobs
|
||||
crontab -l | grep -v "$SPEEDTEST_SCRIPT" | crontab -
|
||||
crontab -l | grep -v "$KEEP_ALIVE_SCRIPT" | crontab -
|
||||
# Clean up temporary files
|
||||
rm -f "$TEMP_FILE"
|
||||
rm -f "$KEEP_ALIVE_SCRIPT"
|
||||
}
|
||||
|
||||
# Function to get current status
|
||||
@@ -86,15 +139,21 @@ get_status() {
|
||||
END_TIME=$(grep "END_TIME=" "$CONFIG_FILE" | cut -d'=' -f2)
|
||||
INTERVAL=$(grep "INTERVAL=" "$CONFIG_FILE" | cut -d'=' -f2)
|
||||
|
||||
# Check if log file exists and get last activity
|
||||
LAST_ACTIVITY=""
|
||||
if [ -f "/tmp/keep_alive.log" ]; then
|
||||
LAST_ACTIVITY=$(tail -n 1 /tmp/keep_alive.log | cut -d: -f1-3)
|
||||
fi
|
||||
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"enabled\":$ENABLED,\"start_time\":\"$START_TIME\",\"end_time\":\"$END_TIME\",\"interval\":$INTERVAL}"
|
||||
echo "{\"enabled\":$ENABLED,\"start_time\":\"$START_TIME\",\"end_time\":\"$END_TIME\",\"interval\":$INTERVAL,\"last_activity\":\"$LAST_ACTIVITY\"}"
|
||||
else
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"enabled\":0,\"start_time\":\"\",\"end_time\":\"\",\"interval\":0}"
|
||||
echo "{\"enabled\":0,\"start_time\":\"\",\"end_time\":\"\",\"interval\":0,\"last_activity\":\"\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -110,7 +169,7 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"status\":\"success\",\"message\":\"Scheduling disabled\"}"
|
||||
echo "{\"status\":\"success\",\"message\":\"Keep-alive scheduling disabled\"}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -142,6 +201,15 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate interval (minimum 5 minutes to avoid too frequent requests)
|
||||
if [ "$INTERVAL" -lt 5 ]; then
|
||||
echo "Status: 400 Bad Request"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"error\":\"Interval must be at least 5 minutes\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate interval
|
||||
if ! validate_interval "$START_TIME" "$END_TIME" "$INTERVAL"; then
|
||||
echo "Status: 400 Bad Request"
|
||||
@@ -151,11 +219,14 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create the worker script
|
||||
create_worker_script
|
||||
|
||||
# Create temporary file for new crontab
|
||||
TEMP_CRON=$(mktemp)
|
||||
|
||||
# Get existing crontab entries (excluding our script)
|
||||
crontab -l 2>/dev/null | grep -v "$SPEEDTEST_SCRIPT" >"$TEMP_CRON"
|
||||
crontab -l 2>/dev/null | grep -v "$KEEP_ALIVE_SCRIPT" >"$TEMP_CRON"
|
||||
|
||||
# Generate and add cron entries
|
||||
generate_cron_time "$START_TIME" "$END_TIME" "$INTERVAL" >>"$TEMP_CRON"
|
||||
@@ -167,10 +238,13 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||
# Save configuration
|
||||
save_config "$START_TIME" "$END_TIME" "$INTERVAL"
|
||||
|
||||
# Initialize log file
|
||||
echo "$(date): Keep-alive scheduling enabled" > /tmp/keep_alive.log
|
||||
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"status\":\"success\",\"message\":\"Keep-alive scheduling enabled\"}"
|
||||
echo "{\"status\":\"success\",\"message\":\"Keep-alive scheduling enabled with download method\"}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
#!/bin/sh
|
||||
|
||||
# QuecManager Log Viewer API
|
||||
# Provides centralized log access for the web interface
|
||||
|
||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
||||
|
||||
# CGI Headers
|
||||
printf "Content-Type: application/json\r\n"
|
||||
printf "Access-Control-Allow-Origin: *\r\n"
|
||||
printf "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n"
|
||||
printf "Access-Control-Allow-Headers: Content-Type\r\n"
|
||||
printf "\r\n"
|
||||
|
||||
# Initialize logs if needed
|
||||
qm_init_logs
|
||||
|
||||
# Parse query parameters
|
||||
QUERY_STRING="${QUERY_STRING:-}"
|
||||
CATEGORY=""
|
||||
SCRIPT=""
|
||||
LEVEL=""
|
||||
LINES="50"
|
||||
SINCE=""
|
||||
|
||||
# Simple parameter parsing
|
||||
if [ -n "$QUERY_STRING" ]; then
|
||||
for param in $(echo "$QUERY_STRING" | tr '&' ' '); do
|
||||
case "$param" in
|
||||
category=*)
|
||||
CATEGORY=$(echo "$param" | cut -d'=' -f2 | sed 's/%20/ /g' | tr -d '"')
|
||||
;;
|
||||
script=*)
|
||||
SCRIPT=$(echo "$param" | cut -d'=' -f2 | sed 's/%20/ /g' | tr -d '"')
|
||||
;;
|
||||
level=*)
|
||||
LEVEL=$(echo "$param" | cut -d'=' -f2 | sed 's/%20/ /g' | tr -d '"')
|
||||
;;
|
||||
lines=*)
|
||||
LINES=$(echo "$param" | cut -d'=' -f2 | tr -d '"')
|
||||
;;
|
||||
since=*)
|
||||
SINCE=$(echo "$param" | cut -d'=' -f2 | sed 's/%20/ /g' | tr -d '"')
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# Validate lines parameter
|
||||
if ! echo "$LINES" | grep -qE '^[0-9]+$' || [ "$LINES" -gt 1000 ]; then
|
||||
LINES="50"
|
||||
fi
|
||||
|
||||
# Function to get available categories
|
||||
get_categories() {
|
||||
printf '{\n'
|
||||
printf ' "categories": [\n'
|
||||
if [ -d "$QM_LOG_DAEMONS" ]; then
|
||||
printf ' "daemons"'
|
||||
[ -d "$QM_LOG_SERVICES" ] || [ -d "$QM_LOG_SETTINGS" ] || [ -d "$QM_LOG_SYSTEM" ] && printf ','
|
||||
printf '\n'
|
||||
fi
|
||||
if [ -d "$QM_LOG_SERVICES" ]; then
|
||||
printf ' "services"'
|
||||
[ -d "$QM_LOG_SETTINGS" ] || [ -d "$QM_LOG_SYSTEM" ] && printf ','
|
||||
printf '\n'
|
||||
fi
|
||||
if [ -d "$QM_LOG_SETTINGS" ]; then
|
||||
printf ' "settings"'
|
||||
[ -d "$QM_LOG_SYSTEM" ] && printf ','
|
||||
printf '\n'
|
||||
fi
|
||||
if [ -d "$QM_LOG_SYSTEM" ]; then
|
||||
printf ' "system"\n'
|
||||
fi
|
||||
printf ' ]\n'
|
||||
printf '}\n'
|
||||
}
|
||||
|
||||
# Function to get available scripts for a category
|
||||
get_scripts() {
|
||||
local cat_dir=""
|
||||
case "$CATEGORY" in
|
||||
"daemons") cat_dir="$QM_LOG_DAEMONS" ;;
|
||||
"services") cat_dir="$QM_LOG_SERVICES" ;;
|
||||
"settings") cat_dir="$QM_LOG_SETTINGS" ;;
|
||||
"system") cat_dir="$QM_LOG_SYSTEM" ;;
|
||||
*)
|
||||
printf '{"error": "Invalid category"}\n'
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -d "$cat_dir" ]; then
|
||||
printf '{"scripts": []}\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '{\n'
|
||||
printf ' "scripts": [\n'
|
||||
|
||||
first=true
|
||||
for logfile in "$cat_dir"/*.log; do
|
||||
if [ -f "$logfile" ]; then
|
||||
if [ "$first" = "false" ]; then
|
||||
printf ',\n'
|
||||
fi
|
||||
script_name=$(basename "$logfile" .log)
|
||||
printf ' "%s"' "$script_name"
|
||||
first=false
|
||||
fi
|
||||
done
|
||||
|
||||
printf '\n ]\n'
|
||||
printf '}\n'
|
||||
}
|
||||
|
||||
# Function to get log entries
|
||||
get_logs() {
|
||||
local logfile=""
|
||||
|
||||
if [ -n "$CATEGORY" ] && [ -n "$SCRIPT" ]; then
|
||||
logfile=$(qm_get_logfile "$CATEGORY" "$SCRIPT")
|
||||
else
|
||||
printf '{"error": "Category and script parameters required"}\n'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$logfile" ]; then
|
||||
printf '{"entries": [], "total": 0}\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get log entries with optional filtering
|
||||
local temp_file="/tmp/quecmanager_log_view.$$"
|
||||
|
||||
# Start with all entries
|
||||
cat "$logfile" > "$temp_file" 2>/dev/null
|
||||
|
||||
# Filter by level if specified
|
||||
if [ -n "$LEVEL" ]; then
|
||||
grep "\[$LEVEL\]" "$temp_file" > "${temp_file}.filtered" 2>/dev/null || touch "${temp_file}.filtered"
|
||||
mv "${temp_file}.filtered" "$temp_file"
|
||||
fi
|
||||
|
||||
# Filter by time if specified (simple grep for now)
|
||||
if [ -n "$SINCE" ]; then
|
||||
grep "$SINCE" "$temp_file" > "${temp_file}.filtered" 2>/dev/null || touch "${temp_file}.filtered"
|
||||
mv "${temp_file}.filtered" "$temp_file"
|
||||
fi
|
||||
|
||||
# Get total count
|
||||
local total_count=$(wc -l < "$temp_file" 2>/dev/null || echo "0")
|
||||
|
||||
# Get last N lines
|
||||
tail -n "$LINES" "$temp_file" > "${temp_file}.final" 2>/dev/null || touch "${temp_file}.final"
|
||||
|
||||
printf '{\n'
|
||||
printf ' "entries": [\n'
|
||||
|
||||
first=true
|
||||
while IFS= read -r line; do
|
||||
if [ -n "$line" ]; then
|
||||
if [ "$first" = "false" ]; then
|
||||
printf ',\n'
|
||||
fi
|
||||
|
||||
# Parse log line (format: [timestamp] [level] [script] [pid] message)
|
||||
timestamp=$(echo "$line" | sed -n 's/^\[\([^]]*\)\].*/\1/p')
|
||||
level=$(echo "$line" | sed -n 's/^[^]]*\] \[\([^]]*\)\].*/\1/p')
|
||||
script=$(echo "$line" | sed -n 's/^[^]]*\] [^]]*\] \[\([^]]*\)\].*/\1/p')
|
||||
pid=$(echo "$line" | sed -n 's/^[^]]*\] [^]]*\] [^]]*\] \[PID:\([^]]*\)\].*/\1/p')
|
||||
message=$(echo "$line" | sed 's/^[^]]*\] [^]]*\] [^]]*\] [^]]*\] //')
|
||||
|
||||
# Escape quotes in message
|
||||
message=$(echo "$message" | sed 's/"/\\"/g')
|
||||
|
||||
printf ' {\n'
|
||||
printf ' "timestamp": "%s",\n' "$timestamp"
|
||||
printf ' "level": "%s",\n' "$level"
|
||||
printf ' "script": "%s",\n' "$script"
|
||||
printf ' "pid": "%s",\n' "$pid"
|
||||
printf ' "message": "%s"\n' "$message"
|
||||
printf ' }'
|
||||
|
||||
first=false
|
||||
fi
|
||||
done < "${temp_file}.final"
|
||||
|
||||
printf '\n ],\n'
|
||||
printf ' "total": %s,\n' "$total_count"
|
||||
printf ' "showing": %s\n' "$LINES"
|
||||
printf '}\n'
|
||||
|
||||
# Cleanup temp files
|
||||
rm -f "$temp_file" "${temp_file}.filtered" "${temp_file}.final" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Main logic
|
||||
case "$REQUEST_METHOD" in
|
||||
"GET")
|
||||
if [ -z "$CATEGORY" ]; then
|
||||
# Return available categories
|
||||
get_categories
|
||||
elif [ -z "$SCRIPT" ]; then
|
||||
# Return available scripts for category
|
||||
get_scripts
|
||||
else
|
||||
# Return log entries
|
||||
get_logs
|
||||
fi
|
||||
;;
|
||||
"OPTIONS")
|
||||
# Handle CORS preflight
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf '{"error": "Method not allowed"}\n'
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Scheduled Reboot Configuration Script
|
||||
# Manages device reboot scheduling using cron
|
||||
# Author: dr-dolomite
|
||||
# Date: 2025-08-10
|
||||
|
||||
# Set content type and CORS headers
|
||||
echo "Content-Type: application/json"
|
||||
echo "Access-Control-Allow-Origin: *"
|
||||
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
|
||||
echo "Access-Control-Allow-Headers: Content-Type"
|
||||
echo ""
|
||||
|
||||
# Configuration
|
||||
CONFIG_DIR="/etc/quecmanager/settings"
|
||||
CONFIG_FILE="$CONFIG_DIR/scheduled_reboot.conf"
|
||||
LOG_FILE="/tmp/scheduled_reboot.log"
|
||||
CRON_FILE="/etc/crontabs/root"
|
||||
|
||||
# Logging function
|
||||
log_message() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Error response function
|
||||
send_error() {
|
||||
local error_code="$1"
|
||||
local error_message="$2"
|
||||
log_message "ERROR: $error_message"
|
||||
echo "{\"status\":\"error\",\"code\":\"$error_code\",\"message\":\"$error_message\"}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Success response function
|
||||
send_success() {
|
||||
local message="$1"
|
||||
local data="$2"
|
||||
log_message "SUCCESS: $message"
|
||||
if [ -n "$data" ]; then
|
||||
echo "{\"status\":\"success\",\"message\":\"$message\",\"data\":$data}"
|
||||
else
|
||||
echo "{\"status\":\"success\",\"message\":\"$message\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure configuration directory exists
|
||||
ensure_config_directory() {
|
||||
if [ ! -d "$CONFIG_DIR" ]; then
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
if [ $? -ne 0 ]; then
|
||||
CONFIG_DIR="/tmp/quecmanager/settings"
|
||||
CONFIG_FILE="$CONFIG_DIR/scheduled_reboot.conf"
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
if [ $? -ne 0 ]; then
|
||||
send_error "DIRECTORY_ERROR" "Failed to create configuration directory"
|
||||
fi
|
||||
fi
|
||||
chmod 755 "$CONFIG_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update cron entry
|
||||
update_cron() {
|
||||
local enabled="$1"
|
||||
local time="$2"
|
||||
local days="$3"
|
||||
|
||||
# Create a temporary file for the new crontab
|
||||
local temp_cron=$(mktemp)
|
||||
|
||||
# If crontab exists, copy all non-QuecManager reboot entries
|
||||
if [ -f "$CRON_FILE" ]; then
|
||||
grep -v "# QuecManager scheduled reboot$" "$CRON_FILE" > "$temp_cron"
|
||||
fi
|
||||
|
||||
if [ "$enabled" = "true" ]; then
|
||||
# Extract hours and minutes from time (HH:MM format)
|
||||
local minutes=$(echo "$time" | cut -d':' -f2)
|
||||
local hours=$(echo "$time" | cut -d':' -f1)
|
||||
|
||||
# Convert days array to cron format (0-6, where 0 is Sunday)
|
||||
local cron_days=""
|
||||
echo "$days" | grep -q '"sunday"' && cron_days="${cron_days}0,"
|
||||
echo "$days" | grep -q '"monday"' && cron_days="${cron_days}1,"
|
||||
echo "$days" | grep -q '"tuesday"' && cron_days="${cron_days}2,"
|
||||
echo "$days" | grep -q '"wednesday"' && cron_days="${cron_days}3,"
|
||||
echo "$days" | grep -q '"thursday"' && cron_days="${cron_days}4,"
|
||||
echo "$days" | grep -q '"friday"' && cron_days="${cron_days}5,"
|
||||
echo "$days" | grep -q '"saturday"' && cron_days="${cron_days}6,"
|
||||
|
||||
# Remove trailing comma
|
||||
cron_days=$(echo "$cron_days" | sed 's/,$//')
|
||||
|
||||
if [ -n "$cron_days" ]; then
|
||||
# Add new cron entry to our temporary file
|
||||
echo "$minutes $hours * * $cron_days /sbin/reboot # QuecManager scheduled reboot" >> "$temp_cron"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure the crontabs directory exists
|
||||
if [ ! -d "/etc/crontabs" ]; then
|
||||
mkdir -p /etc/crontabs
|
||||
chmod 755 /etc/crontabs
|
||||
fi
|
||||
|
||||
# Move the temporary file to the actual crontab and set permissions
|
||||
mv "$temp_cron" "$CRON_FILE"
|
||||
chmod 600 "$CRON_FILE"
|
||||
|
||||
# Always restart cron to ensure changes take effect
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
# Save reboot configuration
|
||||
save_config() {
|
||||
local enabled="$1"
|
||||
local time="$2"
|
||||
local days="$3"
|
||||
|
||||
ensure_config_directory
|
||||
|
||||
# Validate days is a proper JSON array
|
||||
if ! echo "$days" | grep -q '^\[.*\]$'; then
|
||||
days='["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]'
|
||||
fi
|
||||
|
||||
# Create or update config file with proper JSON handling
|
||||
cat > "$CONFIG_FILE" << EOF
|
||||
REBOOT_ENABLED=$enabled
|
||||
REBOOT_TIME=$time
|
||||
REBOOT_DAYS=$days
|
||||
EOF
|
||||
|
||||
chmod 644 "$CONFIG_FILE"
|
||||
|
||||
# Update cron entry
|
||||
update_cron "$enabled" "$time" "$days"
|
||||
}
|
||||
|
||||
# Get current configuration
|
||||
get_config() {
|
||||
local enabled="false"
|
||||
local time="03:00"
|
||||
local days='["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]'
|
||||
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# Read the config file line by line to handle JSON properly
|
||||
while IFS='=' read -r key value; do
|
||||
case "$key" in
|
||||
REBOOT_ENABLED)
|
||||
enabled="$value"
|
||||
;;
|
||||
REBOOT_TIME)
|
||||
time="$value"
|
||||
;;
|
||||
REBOOT_DAYS)
|
||||
# Only update days if the value is a valid JSON array
|
||||
if echo "$value" | grep -q '^\[.*\]$'; then
|
||||
days="$value"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done < "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Ensure proper JSON formatting
|
||||
echo "{\"enabled\":$enabled,\"time\":\"$time\",\"days\":$days}"
|
||||
}
|
||||
|
||||
# Handle GET request
|
||||
handle_get() {
|
||||
local config=$(get_config)
|
||||
send_success "Configuration retrieved" "$config"
|
||||
}
|
||||
|
||||
# Handle POST request
|
||||
handle_post() {
|
||||
# Read POST data
|
||||
local content_length=${CONTENT_LENGTH:-0}
|
||||
if [ "$content_length" -gt 0 ]; then
|
||||
local post_data=$(dd bs=$content_length count=1 2>/dev/null)
|
||||
|
||||
# Extract values using grep and sed
|
||||
local enabled=$(echo "$post_data" | grep -o '"enabled":\s*\(true\|false\)' | cut -d':' -f2 | tr -d ' ')
|
||||
local time=$(echo "$post_data" | grep -o '"time":"[^"]*"' | cut -d'"' -f4)
|
||||
local days=$(echo "$post_data" | grep -o '"days":\s*\[[^]]*\]' | cut -d':' -f2 | tr -d ' ')
|
||||
|
||||
# Validate input
|
||||
if [ -z "$enabled" ] || [ -z "$time" ] || [ -z "$days" ]; then
|
||||
send_error "INVALID_INPUT" "Missing required fields"
|
||||
return
|
||||
fi
|
||||
|
||||
# Validate time format (HH:MM)
|
||||
if ! echo "$time" | grep -qE '^([01]?[0-9]|2[0-3]):[0-5][0-9]$'; then
|
||||
send_error "INVALID_TIME" "Invalid time format. Use HH:MM (24-hour)"
|
||||
return
|
||||
fi
|
||||
|
||||
# Save configuration
|
||||
save_config "$enabled" "$time" "$days"
|
||||
send_success "Configuration updated successfully" "$(get_config)"
|
||||
|
||||
else
|
||||
send_error "NO_DATA" "No data provided"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle DELETE request
|
||||
handle_delete() {
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# Remove cron entry first
|
||||
update_cron "false" "00:00" "[]"
|
||||
|
||||
# Remove config file
|
||||
rm -f "$CONFIG_FILE"
|
||||
send_success "Configuration reset to default" "$(get_config)"
|
||||
else
|
||||
send_error "NOT_FOUND" "Configuration not found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle OPTIONS request
|
||||
handle_options() {
|
||||
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
|
||||
echo "Access-Control-Allow-Headers: Content-Type"
|
||||
echo "Access-Control-Max-Age: 86400"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Main execution
|
||||
log_message "Scheduled reboot script called with method: ${REQUEST_METHOD:-GET}"
|
||||
|
||||
case "${REQUEST_METHOD:-GET}" in
|
||||
GET)
|
||||
handle_get
|
||||
;;
|
||||
POST)
|
||||
handle_post
|
||||
;;
|
||||
DELETE)
|
||||
handle_delete
|
||||
;;
|
||||
OPTIONS)
|
||||
handle_options
|
||||
;;
|
||||
*)
|
||||
send_error "METHOD_NOT_ALLOWED" "HTTP method ${REQUEST_METHOD} not supported"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user