Revert "Official Hot Fix for QuecManager 2.3.0"
This reverts commit 6bd2c7ea52.
This commit is contained in:
@@ -2,40 +2,11 @@
|
|||||||
# AT Queue Client for OpenWRT
|
# AT Queue Client for OpenWRT
|
||||||
# Located in /www/cgi-bin/services/at_queue_client
|
# Located in /www/cgi-bin/services/at_queue_client
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
AUTH_FILE="/tmp/auth_success"
|
AUTH_FILE="/tmp/auth_success"
|
||||||
QUEUE_DIR="/tmp/at_queue"
|
QUEUE_DIR="/tmp/at_queue"
|
||||||
RESULTS_DIR="$QUEUE_DIR/results"
|
RESULTS_DIR="$QUEUE_DIR/results"
|
||||||
QUEUE_MANAGER="/www/cgi-bin/services/at_queue_manager.sh"
|
QUEUE_MANAGER="/www/cgi-bin/services/at_queue_manager.sh"
|
||||||
POLL_INTERVAL=0.01
|
POLL_INTERVAL=0.01
|
||||||
SCRIPT_NAME_LOG="at_queue_client"
|
|
||||||
|
|
||||||
# Logging function - uses both centralized and system logging
|
|
||||||
log_at_queue_client() {
|
|
||||||
local level="$1"
|
|
||||||
local message="$2"
|
|
||||||
|
|
||||||
# Use centralized logging
|
|
||||||
case "$level" in
|
|
||||||
"error")
|
|
||||||
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"warn")
|
|
||||||
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"debug")
|
|
||||||
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Also maintain system logging for compatibility
|
|
||||||
logger -t at_queue -p "daemon.$level" "$message"
|
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 [options] <AT command>"
|
echo "Usage: $0 [options] <AT command>"
|
||||||
@@ -49,14 +20,14 @@ usage() {
|
|||||||
# Output JSON response
|
# Output JSON response
|
||||||
output_json() {
|
output_json() {
|
||||||
local content="$1"
|
local content="$1"
|
||||||
local headers="${2:-1}" # Default to showing headers
|
local headers="${2:-1}" # Default to showing headers
|
||||||
echo "$content"
|
echo "$content"
|
||||||
}
|
}
|
||||||
|
|
||||||
# URL decode function
|
# URL decode function
|
||||||
urldecode() {
|
urldecode() {
|
||||||
local encoded="$1"
|
local encoded="$1"
|
||||||
log_at_queue_client "debug" "urldecode: input='$encoded'"
|
logger -t at_queue -p daemon.debug "urldecode: input='$encoded'"
|
||||||
|
|
||||||
# Handle %2B -> + and %22 -> " conversions
|
# Handle %2B -> + and %22 -> " conversions
|
||||||
local decoded="${encoded//%2B/+}"
|
local decoded="${encoded//%2B/+}"
|
||||||
@@ -64,23 +35,10 @@ urldecode() {
|
|||||||
# Then handle other encoded characters
|
# Then handle other encoded characters
|
||||||
decoded=$(printf '%b' "${decoded//%/\\x}")
|
decoded=$(printf '%b' "${decoded//%/\\x}")
|
||||||
|
|
||||||
log_at_queue_client "debug" "urldecode: output='$decoded'"
|
logger -t at_queue -p daemon.debug "urldecode: output='$decoded'"
|
||||||
echo "$decoded"
|
echo "$decoded"
|
||||||
}
|
}
|
||||||
|
|
||||||
# URL encode function (simplified for AT commands)
|
|
||||||
urlencode() {
|
|
||||||
local string="$1"
|
|
||||||
# Simple encoding for common AT command characters
|
|
||||||
string="${string// /%20}"
|
|
||||||
string="${string//+/%2B}"
|
|
||||||
string="${string//\"/%22}"
|
|
||||||
string="${string//=/%3D}"
|
|
||||||
string="${string//&/%26}"
|
|
||||||
string="${string//?/%3F}"
|
|
||||||
echo "$string"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Extract command ID from response with improved error handling
|
# Extract command ID from response with improved error handling
|
||||||
get_command_id() {
|
get_command_id() {
|
||||||
local response="$1"
|
local response="$1"
|
||||||
@@ -114,19 +72,19 @@ get_command_id() {
|
|||||||
# Normalize AT command
|
# Normalize AT command
|
||||||
normalize_at_command() {
|
normalize_at_command() {
|
||||||
local cmd="$1"
|
local cmd="$1"
|
||||||
log_at_queue_client "debug" "normalize: input='$cmd'"
|
logger -t at_queue -p daemon.debug "normalize: input='$cmd'"
|
||||||
|
|
||||||
# URL decode the command
|
# URL decode the command
|
||||||
cmd=$(urldecode "$cmd")
|
cmd=$(urldecode "$cmd")
|
||||||
log_at_queue_client "debug" "normalize: after urldecode='$cmd'"
|
logger -t at_queue -p daemon.debug "normalize: after urldecode='$cmd'"
|
||||||
|
|
||||||
# Remove any carriage returns or newlines
|
# Remove any carriage returns or newlines
|
||||||
cmd=$(echo "$cmd" | tr -d '\r\n')
|
cmd=$(echo "$cmd" | tr -d '\r\n')
|
||||||
log_at_queue_client "debug" "normalize: after cleanup='$cmd'"
|
logger -t at_queue -p daemon.debug "normalize: after cleanup='$cmd'"
|
||||||
|
|
||||||
# Trim leading/trailing whitespace while preserving quotes
|
# Trim leading/trailing whitespace while preserving quotes
|
||||||
cmd=$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
cmd=$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
log_at_queue_client "debug" "normalize: final output='$cmd'"
|
logger -t at_queue -p daemon.debug "normalize: final output='$cmd'"
|
||||||
|
|
||||||
echo "$cmd"
|
echo "$cmd"
|
||||||
}
|
}
|
||||||
@@ -143,7 +101,7 @@ submit_command() {
|
|||||||
|
|
||||||
# Submit using appropriate method
|
# Submit using appropriate method
|
||||||
if [ "${SCRIPT_NAME}" != "" ]; then
|
if [ "${SCRIPT_NAME}" != "" ]; then
|
||||||
# CGI mode - direct execution like the original working version
|
# CGI mode - direct execution
|
||||||
local escaped_cmd=$(echo "$cmd" | sed 's/"/\\"/g')
|
local escaped_cmd=$(echo "$cmd" | sed 's/"/\\"/g')
|
||||||
QUERY_STRING="action=enqueue&command=${escaped_cmd}&priority=$priority" "$QUEUE_MANAGER"
|
QUERY_STRING="action=enqueue&command=${escaped_cmd}&priority=$priority" "$QUEUE_MANAGER"
|
||||||
else
|
else
|
||||||
@@ -160,7 +118,7 @@ check_result() {
|
|||||||
if [ -f "$RESULTS_DIR/$cmd_id.json" ]; then
|
if [ -f "$RESULTS_DIR/$cmd_id.json" ]; then
|
||||||
local result_content=$(cat "$RESULTS_DIR/$cmd_id.json")
|
local result_content=$(cat "$RESULTS_DIR/$cmd_id.json")
|
||||||
if [ -z "$result_content" ]; then
|
if [ -z "$result_content" ]; then
|
||||||
log_at_queue_client "error" "Empty result file for command ID: $cmd_id"
|
logger -t at_queue -p daemon.error "Empty result file for command ID: $cmd_id"
|
||||||
local error_json="{\"error\":\"Empty result file\",\"command_id\":\"$cmd_id\"}"
|
local error_json="{\"error\":\"Empty result file\",\"command_id\":\"$cmd_id\"}"
|
||||||
output_json "$error_json" "$show_headers"
|
output_json "$error_json" "$show_headers"
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# On SDXPINN and (assumed) SDXLEMUR with OpenWRT Overlay, the environment NEEDS to be /bin/sh,
|
|
||||||
# whereas QTI environment on SDXLEMUR uses /bin/bash. This assumption requires verification.
|
|
||||||
# Set content-type for JSON response
|
# Set content-type for JSON response
|
||||||
printf "Content-type: application/json\r\n"
|
echo "Content-type: application/json"
|
||||||
printf "\r\n"
|
echo ""
|
||||||
|
|
||||||
# Define paths and constants to match queue system
|
# Define paths and constants to match queue system
|
||||||
QUEUE_DIR="/tmp/at_queue"
|
QUEUE_DIR="/tmp/at_queue"
|
||||||
@@ -14,11 +13,11 @@ TOKEN_FILE="$QUEUE_DIR/token"
|
|||||||
# Logging function (minimized)
|
# Logging function (minimized)
|
||||||
log_message() {
|
log_message() {
|
||||||
# Only log errors and critical info
|
# Only log errors and critical info
|
||||||
if [ "$1" = "error" ] || [ "$1" = "crit" ]; then
|
if [ "$1" = "error" ] || [ "$1" = "crit" ]; then
|
||||||
logger -t at_queue -p "daemon.$1" "$2"
|
logger -t at_queue -p "daemon.$1" "$2"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
mkdir -m755 -p ${QUEUE_DIR}
|
|
||||||
# Enhanced JSON string escaping function
|
# Enhanced JSON string escaping function
|
||||||
escape_json() {
|
escape_json() {
|
||||||
printf '%s' "$1" | awk '
|
printf '%s' "$1" | awk '
|
||||||
@@ -37,46 +36,39 @@ escape_json() {
|
|||||||
|
|
||||||
# Acquire token directly (avoid CGI overhead)
|
# Acquire token directly (avoid CGI overhead)
|
||||||
acquire_token() {
|
acquire_token() {
|
||||||
priority="${1:-10}"
|
local priority="${1:-10}"
|
||||||
max_attempts=10
|
local max_attempts=10
|
||||||
attempt=0
|
local attempt=0
|
||||||
log_message "debug" "Acquiring token"
|
|
||||||
while [ $attempt -lt $max_attempts ]; do
|
while [ $attempt -lt $max_attempts ]; do
|
||||||
# Check if token file exists
|
# Check if token file exists
|
||||||
if [ -f "$TOKEN_FILE" ]; then
|
if [ -f "$TOKEN_FILE" ]; then
|
||||||
current_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id' 2>/dev/null)
|
local current_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id' 2>/dev/null)
|
||||||
current_priority=$(cat "$TOKEN_FILE" | jsonfilter -e '@.priority' 2>/dev/null)
|
local current_priority=$(cat "$TOKEN_FILE" | jsonfilter -e '@.priority' 2>/dev/null)
|
||||||
timestamp=$(cat "$TOKEN_FILE" | jsonfilter -e '@.timestamp' 2>/dev/null)
|
local timestamp=$(cat "$TOKEN_FILE" | jsonfilter -e '@.timestamp' 2>/dev/null)
|
||||||
current_time=$(date +%s)
|
local current_time=$(date +%s)
|
||||||
log_message "info" "current_holder: ${current_holder}"
|
|
||||||
log_message "info" "current_priority: ${current_priority}"
|
|
||||||
log_message "info" "timestamp: ${timestamp}"
|
|
||||||
log_message "info" "current_time: ${current_time}"
|
|
||||||
# Check for expired token (> 30 seconds old)
|
# Check for expired token (> 30 seconds old)
|
||||||
if [ $((current_time - timestamp)) -gt 30 ] || [ -z "$current_holder" ]; then
|
if [ $((current_time - timestamp)) -gt 30 ] || [ -z "$current_holder" ]; then
|
||||||
# Remove expired token
|
# Remove expired token
|
||||||
log_message "debug" "Removing token, cur time minus timestamp gt 30 or current-holder not set"
|
|
||||||
rm -f "$TOKEN_FILE" 2>/dev/null
|
rm -f "$TOKEN_FILE" 2>/dev/null
|
||||||
elif [ $priority -lt $current_priority ]; then
|
elif [ $priority -lt $current_priority ]; then
|
||||||
# Preempt lower priority token
|
# Preempt lower priority token
|
||||||
log_message "debug" "Current priority lower priority than other task"
|
|
||||||
rm -f "$TOKEN_FILE" 2>/dev/null
|
rm -f "$TOKEN_FILE" 2>/dev/null
|
||||||
else
|
else
|
||||||
# Try again
|
# Try again
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
attempt=$((attempt + 1))
|
attempt=$((attempt + 1))
|
||||||
log_message "debug" "Trying again $attempt"
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
log_message "debug" "No token file"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Try to create token file
|
# Try to create token file
|
||||||
printf "{\"id\":\"$LOCK_ID\",\"priority\":$priority,\"timestamp\":$(date +%s)}" >"$TOKEN_FILE" 2>/dev/null
|
echo "{\"id\":\"$LOCK_ID\",\"priority\":$priority,\"timestamp\":$(date +%s)}" >"$TOKEN_FILE" 2>/dev/null
|
||||||
chmod 644 "$TOKEN_FILE" 2>/dev/null
|
chmod 644 "$TOKEN_FILE" 2>/dev/null
|
||||||
|
|
||||||
# Verify we got the token
|
# Verify we got the token
|
||||||
holder=$(cat "$TOKEN_FILE" 2>/dev/null | jsonfilter -e '@.id' 2>/dev/null)
|
local holder=$(cat "$TOKEN_FILE" 2>/dev/null | jsonfilter -e '@.id' 2>/dev/null)
|
||||||
if [ "$holder" = "$LOCK_ID" ]; then
|
if [ "$holder" = "$LOCK_ID" ]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -87,16 +79,13 @@ acquire_token() {
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Release token directly
|
# Release token directly
|
||||||
release_token() {
|
release_token() {
|
||||||
log_message "debug" "Release Token"
|
|
||||||
# Only remove if it's our token
|
# Only remove if it's our token
|
||||||
if [ -f "$TOKEN_FILE" ]; then
|
if [ -f "$TOKEN_FILE" ]; then
|
||||||
log_message "debug" "Has Token file"
|
local current_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id' 2>/dev/null)
|
||||||
current_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id' 2>/dev/null)
|
|
||||||
log_message "debug" "Release Token, Current Holder: ${current_holder}"
|
|
||||||
if [ "$current_holder" = "$LOCK_ID" ]; then
|
if [ "$current_holder" = "$LOCK_ID" ]; then
|
||||||
log_message "debug" "Release Token, Current Holder: ${current_holder}, removing token"
|
|
||||||
rm -f "$TOKEN_FILE" 2>/dev/null
|
rm -f "$TOKEN_FILE" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -104,21 +93,18 @@ release_token() {
|
|||||||
|
|
||||||
# Direct AT command execution with minimal overhead
|
# Direct AT command execution with minimal overhead
|
||||||
execute_at_command() {
|
execute_at_command() {
|
||||||
CMD="$1"
|
local CMD="$1"
|
||||||
sms_tool at "$CMD" -t 3 2>/dev/null
|
sms_tool at "$CMD" -t 3 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Batch process all commands with a single token
|
# Batch process all commands with a single token
|
||||||
process_all_commands() {
|
process_all_commands() {
|
||||||
commands="$1"
|
local commands="$1"
|
||||||
priority="${2:-10}"
|
local priority="${2:-10}"
|
||||||
first=1
|
local first=1
|
||||||
log_message "info" "Before acquire_token check"
|
|
||||||
acquire_token "$priority"
|
|
||||||
trying=$?
|
|
||||||
log_message "debug" "trying: ${trying}"
|
|
||||||
# Acquire a single token for all commands
|
# Acquire a single token for all commands
|
||||||
if [ $trying -ne 0 ]; then
|
if ! acquire_token "$priority"; then
|
||||||
log_message "error" "Failed to acquire token for batch processing"
|
log_message "error" "Failed to acquire token for batch processing"
|
||||||
# Return all failed responses
|
# Return all failed responses
|
||||||
printf '['
|
printf '['
|
||||||
@@ -129,7 +115,7 @@ process_all_commands() {
|
|||||||
ESCAPED_CMD=$(escape_json "$cmd")
|
ESCAPED_CMD=$(escape_json "$cmd")
|
||||||
printf '{"command":"%s","response":"Failed to acquire token","status":"error"}' "${ESCAPED_CMD}"
|
printf '{"command":"%s","response":"Failed to acquire token","status":"error"}' "${ESCAPED_CMD}"
|
||||||
done
|
done
|
||||||
printf ']\r\n'
|
printf ']\n'
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -138,9 +124,10 @@ process_all_commands() {
|
|||||||
for cmd in $commands; do
|
for cmd in $commands; do
|
||||||
[ $first -eq 0 ] && printf ','
|
[ $first -eq 0 ] && printf ','
|
||||||
first=0
|
first=0
|
||||||
|
|
||||||
OUTPUT=$(execute_at_command "$cmd")
|
OUTPUT=$(execute_at_command "$cmd")
|
||||||
CMD_STATUS=$?
|
local CMD_STATUS=$?
|
||||||
log_message "debug" "CMD: ${cmd}, OUTPUT: ${OUTPUT}, CMD_STAT: ${CMD_STATUS}"
|
|
||||||
ESCAPED_CMD=$(escape_json "$cmd")
|
ESCAPED_CMD=$(escape_json "$cmd")
|
||||||
ESCAPED_OUTPUT=$(escape_json "$OUTPUT")
|
ESCAPED_OUTPUT=$(escape_json "$OUTPUT")
|
||||||
|
|
||||||
@@ -153,7 +140,8 @@ process_all_commands() {
|
|||||||
"${ESCAPED_CMD}"
|
"${ESCAPED_CMD}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
printf ']\r\n'
|
printf ']\n'
|
||||||
|
|
||||||
# Release token after all commands are done
|
# Release token after all commands are done
|
||||||
release_token
|
release_token
|
||||||
return 0
|
return 0
|
||||||
@@ -196,14 +184,15 @@ if echo "$COMMANDS" | grep -qi "AT+QSCAN"; then
|
|||||||
PRIORITY=1
|
PRIORITY=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# (
|
# Process commands with timeout protection
|
||||||
# sleep 60
|
(
|
||||||
# kill -TERM $$
|
sleep 60
|
||||||
# ) &
|
kill -TERM $$ 2>/dev/null
|
||||||
# TIMEOUT_PID=$!
|
) &
|
||||||
|
TIMEOUT_PID=$!
|
||||||
|
|
||||||
process_all_commands "$COMMANDS" "$PRIORITY"
|
process_all_commands "$COMMANDS" "$PRIORITY"
|
||||||
|
|
||||||
# kill $TIMEOUT_PID 2>/dev/null
|
|
||||||
release_token
|
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
kill $TIMEOUT_PID 2>/dev/null
|
||||||
|
release_token
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ read -r POST_DATA
|
|||||||
|
|
||||||
# Debug log for generated hash
|
# Debug log for generated hash
|
||||||
DEBUG_LOG="/tmp/auth.log"
|
DEBUG_LOG="/tmp/auth.log"
|
||||||
AUTH_FILE="/tmp/auth_success"
|
|
||||||
# Extract the password from POST data (URL encoded)
|
# Extract the password from POST data (URL encoded)
|
||||||
USER="root"
|
USER="root"
|
||||||
INPUT_PASSWORD=$(echo "$POST_DATA" | grep -o 'password=[^&]*' | cut -d= -f2-)
|
INPUT_PASSWORD=$(echo "$POST_DATA" | grep -o 'password=[^&]*' | cut -d= -f2-)
|
||||||
@@ -54,43 +54,9 @@ GENERATED_HASH=$(printf '%s' "$INPUT_PASSWORD" | openssl passwd -1 -salt "$SALT"
|
|||||||
# Log generated hash for debugging
|
# Log generated hash for debugging
|
||||||
printf "Generated hash: %s\n" "$GENERATED_HASH" >> "$DEBUG_LOG"
|
printf "Generated hash: %s\n" "$GENERATED_HASH" >> "$DEBUG_LOG"
|
||||||
|
|
||||||
# Check if the request for AUTH contains the Authorization Header so as to assure we're not at an initial login
|
|
||||||
SUPPLIED_TOKEN="${HTTP_AUTHORIZATION}"
|
|
||||||
# Compare the generated hash with the one in the shadow file
|
# Compare the generated hash with the one in the shadow file
|
||||||
if [ "$GENERATED_HASH" = "$USER_HASH" ]; then
|
if [ "$GENERATED_HASH" = "$USER_HASH" ]; then
|
||||||
# If the token is supplied, use it; otherwise, generate a new one and store it in the auth file
|
echo '{"state":"success"}'
|
||||||
if [ "$SUPPLIED_TOKEN" != "" ]; then
|
|
||||||
TOKEN="$SUPPLIED_TOKEN"
|
|
||||||
else
|
|
||||||
TOKEN=$(head -c 16 /dev/urandom | hexdump -v -e '/1 "%02x"')
|
|
||||||
CREATED_DATE=$(date +"%Y-%m-%dT%H:%M:%S")
|
|
||||||
touch ${AUTH_FILE}
|
|
||||||
echo "${CREATED_DATE} ${TOKEN}" >> ${AUTH_FILE}
|
|
||||||
echo "" >> ${AUTH_FILE}
|
|
||||||
fi
|
|
||||||
echo "{\"state\":\"success\",\"token\":\"${TOKEN}\"}"
|
|
||||||
else
|
else
|
||||||
# Remove token from file
|
|
||||||
if [ -n ${TOKEN} ]; then
|
|
||||||
sed -i -e "s/.*${TOKEN}.*//g" ${AUTH_FILE} 2>/dev/null
|
|
||||||
fi
|
|
||||||
echo '{"state":"failed", "message":"Authentication failed"}'
|
echo '{"state":"failed", "message":"Authentication failed"}'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# AUTH_FILE cleanup process, Remove any token lines older than 2 hours from AUTH_FILE
|
|
||||||
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
|
|
||||||
NOW_TIME=$(date +%s)
|
|
||||||
TMP_FILE=$(mktemp)
|
|
||||||
while read -r line; do
|
|
||||||
if [ -n "$(echo "$line" | tr -d '[:space:]')" ]; then
|
|
||||||
# Extract the date from the line and convert it to a timestamp
|
|
||||||
TOKEN_DATE=$(echo "$line" | awk '{print $1}' | sed 's/T/ /')
|
|
||||||
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
|
|
||||||
# If date is valid and not older than MAX_AGE, keep the line
|
|
||||||
if [ -n "$TOKEN_TIME" ] && [ $((NOW_TIME - TOKEN_TIME)) -le $MAX_AGE ]; then
|
|
||||||
echo "$line" >> "$TMP_FILE"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done < "$AUTH_FILE"
|
|
||||||
|
|
||||||
mv "$TMP_FILE" "$AUTH_FILE"
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
#!/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
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/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,269 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
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() {
|
|
||||||
echo "$1" | awk -F: '{print $1 * 60 + $2}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to validate time interval
|
|
||||||
validate_interval() {
|
|
||||||
START_TIME=$1
|
|
||||||
END_TIME=$2
|
|
||||||
INTERVAL_MINUTES=$3
|
|
||||||
|
|
||||||
# Convert times to minutes
|
|
||||||
START_MINUTES=$(time_to_minutes "$START_TIME")
|
|
||||||
END_MINUTES=$(time_to_minutes "$END_TIME")
|
|
||||||
|
|
||||||
# Calculate duration between start and end time
|
|
||||||
if [ $END_MINUTES -lt $START_MINUTES ]; then
|
|
||||||
# Handle case where end time is on the next day
|
|
||||||
DURATION=$((1440 - START_MINUTES + END_MINUTES))
|
|
||||||
else
|
|
||||||
DURATION=$((END_MINUTES - START_MINUTES))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if interval is longer than duration
|
|
||||||
if [ $INTERVAL_MINUTES -gt $DURATION ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
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
|
|
||||||
END_TIME=$2
|
|
||||||
INTERVAL=$3
|
|
||||||
|
|
||||||
START_HOUR=$(echo "$START_TIME" | cut -d: -f1 | sed 's/^0//')
|
|
||||||
START_MIN=$(echo "$START_TIME" | cut -d: -f2)
|
|
||||||
END_HOUR=$(echo "$END_TIME" | cut -d: -f1 | sed 's/^0//')
|
|
||||||
END_MIN=$(echo "$END_TIME" | cut -d: -f2)
|
|
||||||
|
|
||||||
# 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 * * * $KEEP_ALIVE_SCRIPT"
|
|
||||||
echo "*/$INTERVAL 0-$((END_HOUR - 1)) * * * $KEEP_ALIVE_SCRIPT"
|
|
||||||
else
|
|
||||||
echo "*/$INTERVAL $START_HOUR-$((END_HOUR - 1)) * * * $KEEP_ALIVE_SCRIPT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to urldecode
|
|
||||||
urldecode() {
|
|
||||||
echo -e "$(echo "$1" | sed 's/+/ /g;s/%\([0-9A-F][0-9A-F]\)/\\x\1/g')"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to save configuration
|
|
||||||
save_config() {
|
|
||||||
echo "START_TIME=$1" >"$CONFIG_FILE"
|
|
||||||
echo "END_TIME=$2" >>"$CONFIG_FILE"
|
|
||||||
echo "INTERVAL=$3" >>"$CONFIG_FILE"
|
|
||||||
echo "ENABLED=1" >>"$CONFIG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to disable scheduling
|
|
||||||
disable_scheduling() {
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
sed -i 's/ENABLED=1/ENABLED=0/' "$CONFIG_FILE"
|
|
||||||
fi
|
|
||||||
# Remove any existing cron jobs
|
|
||||||
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
|
|
||||||
get_status() {
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
ENABLED=$(grep "ENABLED=" "$CONFIG_FILE" | cut -d'=' -f2)
|
|
||||||
START_TIME=$(grep "START_TIME=" "$CONFIG_FILE" | cut -d'=' -f2)
|
|
||||||
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,\"last_activity\":\"$LAST_ACTIVITY\"}"
|
|
||||||
else
|
|
||||||
echo "Status: 200 OK"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"enabled\":0,\"start_time\":\"\",\"end_time\":\"\",\"interval\":0,\"last_activity\":\"\"}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle POST requests
|
|
||||||
if [ "$REQUEST_METHOD" = "POST" ]; then
|
|
||||||
# Read POST data
|
|
||||||
read -r POST_DATA
|
|
||||||
|
|
||||||
# Check if disabling is requested
|
|
||||||
echo "$POST_DATA" | grep -q "disable=true"
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
disable_scheduling
|
|
||||||
echo "Status: 200 OK"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"status\":\"success\",\"message\":\"Keep-alive scheduling disabled\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract times and interval
|
|
||||||
START_TIME=$(echo "$POST_DATA" | grep -o 'start_time=[^&]*' | cut -d'=' -f2)
|
|
||||||
END_TIME=$(echo "$POST_DATA" | grep -o 'end_time=[^&]*' | cut -d'=' -f2)
|
|
||||||
INTERVAL=$(echo "$POST_DATA" | grep -o 'interval=[^&]*' | cut -d'=' -f2)
|
|
||||||
|
|
||||||
# Decode times
|
|
||||||
START_TIME=$(urldecode "$START_TIME")
|
|
||||||
END_TIME=$(urldecode "$END_TIME")
|
|
||||||
INTERVAL=$(urldecode "$INTERVAL")
|
|
||||||
|
|
||||||
# Validate times
|
|
||||||
if [ -z "$START_TIME" ] || [ -z "$END_TIME" ] || [ -z "$INTERVAL" ]; then
|
|
||||||
echo "Status: 400 Bad Request"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"error\":\"Missing start time, end time, or interval\"}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate interval is a number
|
|
||||||
if ! echo "$INTERVAL" | grep -q '^[0-9]\+$'; then
|
|
||||||
echo "Status: 400 Bad Request"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"error\":\"Interval must be a number in minutes\"}"
|
|
||||||
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"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"error\":\"Interval is longer than the time between start and end time\"}"
|
|
||||||
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 "$KEEP_ALIVE_SCRIPT" >"$TEMP_CRON"
|
|
||||||
|
|
||||||
# Generate and add cron entries
|
|
||||||
generate_cron_time "$START_TIME" "$END_TIME" "$INTERVAL" >>"$TEMP_CRON"
|
|
||||||
|
|
||||||
# Install new crontab
|
|
||||||
crontab "$TEMP_CRON"
|
|
||||||
rm "$TEMP_CRON"
|
|
||||||
|
|
||||||
# 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 with download method\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse query string for GET requests
|
|
||||||
if [ "$REQUEST_METHOD" = "GET" ]; then
|
|
||||||
QUERY_STRING=$(echo "$QUERY_STRING" | sed 's/&/\n/g')
|
|
||||||
for param in $QUERY_STRING; do
|
|
||||||
case "$param" in
|
|
||||||
status=*)
|
|
||||||
get_status
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If no valid request is made
|
|
||||||
echo "Status: 400 Bad Request"
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo ""
|
|
||||||
echo "{\"error\":\"Invalid request\"}"
|
|
||||||
exit 1
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Ethernet Hardware Details Fetch Script
|
|
||||||
# Provides ethernet interface information using ethtool
|
|
||||||
|
|
||||||
# Set common headers
|
# Set common headers
|
||||||
echo "Content-Type: application/json"
|
echo "Content-Type: application/json"
|
||||||
echo "Access-Control-Allow-Origin: *"
|
echo "Access-Control-Allow-Origin: *"
|
||||||
@@ -11,7 +8,7 @@ echo ""
|
|||||||
|
|
||||||
# Lock file path
|
# Lock file path
|
||||||
LOCK_FILE="/tmp/hw_details.lock"
|
LOCK_FILE="/tmp/hw_details.lock"
|
||||||
LOCK_TIMEOUT=10 # Maximum wait time in seconds
|
LOCK_TIMEOUT=10 # Maximum wait time in seconds
|
||||||
|
|
||||||
# Function to acquire lock
|
# Function to acquire lock
|
||||||
acquire_lock() {
|
acquire_lock() {
|
||||||
@@ -60,72 +57,63 @@ cleanup() {
|
|||||||
# Set trap for cleanup
|
# Set trap for cleanup
|
||||||
trap cleanup EXIT INT TERM
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Function to get memory information
|
||||||
|
get_memory_info() {
|
||||||
|
free_output=$(free -b)
|
||||||
|
memory_info=$(echo "$free_output" | awk '/Mem:/ {print "{\"total\": " $2 ", \"used\": " $3 ", \"available\": " $7 "}"}')
|
||||||
|
echo "$memory_info"
|
||||||
|
}
|
||||||
|
|
||||||
# Function to get ethernet information
|
# Function to get ethernet information
|
||||||
get_ethernet_info() {
|
get_ethernet_info() {
|
||||||
interface=${1:-eth0}
|
interface=${1:-eth0}
|
||||||
|
# Check if ethtool is installed
|
||||||
# First check if interface exists at all
|
|
||||||
if ! ip link show "$interface" >/dev/null 2>&1; then
|
|
||||||
# Interface doesn't exist - return not connected state
|
|
||||||
echo "{\"link_speed\":\"Not Connected\",\"link_status\":\"no\",\"auto_negotiation\":\"off\",\"connected\":false}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if interface is up (administratively)
|
|
||||||
interface_state=$(ip link show "$interface" 2>/dev/null | grep -o "state [A-Z]*" | cut -d' ' -f2)
|
|
||||||
if [ "$interface_state" = "DOWN" ]; then
|
|
||||||
# Interface exists but is down - return not connected state
|
|
||||||
echo "{\"link_speed\":\"Not Connected\",\"link_status\":\"no\",\"auto_negotiation\":\"off\",\"connected\":false}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if ethtool is available
|
|
||||||
if ! which ethtool >/dev/null 2>&1; then
|
if ! which ethtool >/dev/null 2>&1; then
|
||||||
# Fallback: basic interface info without ethtool
|
error_response "ethtool not found"
|
||||||
echo "{\"link_speed\":\"Unknown\",\"link_status\":\"unknown\",\"auto_negotiation\":\"unknown\",\"connected\":true}"
|
fi
|
||||||
return 0
|
|
||||||
|
# Check if interface exists
|
||||||
|
if ! ip link show "$interface" >/dev/null 2>&1; then
|
||||||
|
error_response "Interface $interface not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run ethtool and capture output
|
# Run ethtool and capture output
|
||||||
ethtool_output=$(ethtool "$interface" 2>/dev/null)
|
ethtool_output=$(ethtool "$interface" 2>/dev/null) || error_response "Failed to get ethernet information"
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# ethtool failed - likely no physical connection
|
|
||||||
echo "{\"link_speed\":\"Not Connected\",\"link_status\":\"no\",\"auto_negotiation\":\"off\",\"connected\":false}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract values using sed instead of grep -P
|
# Extract values using sed instead of grep -P
|
||||||
speed=$(echo "$ethtool_output" | sed -n 's/.*Speed: \([^[:space:]]*\).*/\1/p')
|
speed=$(echo "$ethtool_output" | sed -n 's/.*Speed: \([^[:space:]]*\).*/\1/p' || echo "Unknown")
|
||||||
link_status=$(echo "$ethtool_output" | sed -n 's/.*Link detected: \(yes\|no\).*/\1/p')
|
link_status=$(echo "$ethtool_output" | sed -n 's/.*Link detected: \(yes\|no\).*/\1/p' || echo "unknown")
|
||||||
auto_negotiation=$(echo "$ethtool_output" | sed -n 's/.*Auto-negotiation: \(on\|off\).*/\1/p')
|
auto_negotiation=$(echo "$ethtool_output" | sed -n 's/.*Auto-negotiation: \(on\|off\).*/\1/p' || echo "unknown")
|
||||||
|
|
||||||
# Set defaults if extraction failed
|
# Output JSON
|
||||||
[ -z "$speed" ] && speed="Unknown"
|
echo "{\"link_speed\":\"$speed\",\"link_status\":\"$link_status\",\"auto_negotiation\":\"$auto_negotiation\"}"
|
||||||
[ -z "$link_status" ] && link_status="unknown"
|
|
||||||
[ -z "$auto_negotiation" ] && auto_negotiation="unknown"
|
|
||||||
|
|
||||||
# Check if link is actually detected
|
|
||||||
if [ "$link_status" = "no" ]; then
|
|
||||||
# Physical link not detected - return not connected state
|
|
||||||
echo "{\"link_speed\":\"Not Connected\",\"link_status\":\"no\",\"auto_negotiation\":\"$auto_negotiation\",\"connected\":false}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Link is detected and active - return connected state
|
|
||||||
echo "{\"link_speed\":\"$speed\",\"link_status\":\"$link_status\",\"auto_negotiation\":\"$auto_negotiation\",\"connected\":true}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main execution
|
# Main execution
|
||||||
# Acquire lock before proceeding
|
# Acquire lock before proceeding
|
||||||
acquire_lock
|
acquire_lock
|
||||||
|
|
||||||
# Parse query string for interface parameter
|
# Parse query string for type and interface
|
||||||
|
type=$(echo "$QUERY_STRING" | sed -n 's/.*type=\([^&]*\).*/\1/p')
|
||||||
interface=$(echo "$QUERY_STRING" | sed -n 's/.*interface=\([^&]*\).*/\1/p')
|
interface=$(echo "$QUERY_STRING" | sed -n 's/.*interface=\([^&]*\).*/\1/p')
|
||||||
|
|
||||||
# Default interface if not specified
|
# Default interface if not specified
|
||||||
[ -z "$interface" ] && interface="eth0"
|
[ -z "$interface" ] && interface="eth0"
|
||||||
|
|
||||||
# Get ethernet information for the specified interface
|
# Convert type to lowercase using tr
|
||||||
get_ethernet_info "$interface"
|
type=$(echo "$type" | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
# Check type parameter and call appropriate function
|
||||||
|
case "$type" in
|
||||||
|
"memory")
|
||||||
|
get_memory_info
|
||||||
|
;;
|
||||||
|
"eth")
|
||||||
|
get_ethernet_info "$interface"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error_response "Invalid type. Use 'memory' or 'eth'"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Lock will be automatically released by the cleanup trap
|
# Lock will be automatically released by the cleanup trap
|
||||||
@@ -6,15 +6,6 @@
|
|||||||
echo "Content-Type: application/json"
|
echo "Content-Type: application/json"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Check for internet connectivity by pinging 8.8.8.8 twice
|
|
||||||
ping -c 2 8.8.8.8 >/dev/null 2>&1
|
|
||||||
|
|
||||||
# If ping fails, return error immediately
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo '{"error": "Failed to fetch public IP"}'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fetch public IP using multiple fallback methods
|
# Fetch public IP using multiple fallback methods
|
||||||
PUBLIC_IP=$(
|
PUBLIC_IP=$(
|
||||||
curl -s https://api.ipify.org 2>/dev/null || \
|
curl -s https://api.ipify.org 2>/dev/null || \
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Memory Data Fetch Script - Simplified and robust
|
|
||||||
|
|
||||||
# Always set CORS headers first (no conditional OPTIONS handling)
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Handle OPTIONS request and exit early
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "{\"status\":\"success\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only handle GET requests
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" != "GET" ]; then
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Method not allowed\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
MEMORY_JSON="/tmp/quecmanager/memory.json"
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/memory_settings.conf"
|
|
||||||
|
|
||||||
# Check if memory data file exists
|
|
||||||
if [ -f "$MEMORY_JSON" ] && [ -r "$MEMORY_JSON" ]; then
|
|
||||||
# Read the file content
|
|
||||||
memory_data=$(cat "$MEMORY_JSON" 2>/dev/null)
|
|
||||||
|
|
||||||
# Check if we got content and it looks like JSON
|
|
||||||
if [ -n "$memory_data" ] && echo "$memory_data" | grep -q '"total"'; then
|
|
||||||
# File exists and has content, return it as-is if it's valid JSON
|
|
||||||
if echo "$memory_data" | grep -q '"used"' && echo "$memory_data" | grep -q '"available"'; then
|
|
||||||
echo "{\"status\":\"success\",\"data\":$memory_data}"
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Invalid memory data format\"}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Memory data file is empty or corrupted\"}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# No memory file exists - check configuration
|
|
||||||
if [ -f "$CONFIG_FILE" ] && [ -r "$CONFIG_FILE" ]; then
|
|
||||||
# Check if memory monitoring is enabled
|
|
||||||
if grep -q "^MEMORY_ENABLED=true" "$CONFIG_FILE" 2>/dev/null; then
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Memory daemon starting up\"}"
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Memory monitoring disabled\"}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Memory monitoring not configured\"}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always exit cleanly
|
|
||||||
exit 0
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Memory Service Fetch Script
|
|
||||||
# Returns current memory configuration and status
|
|
||||||
|
|
||||||
# Handle OPTIONS request first
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "Content-Type: text/plain"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo "Access-Control-Max-Age: 86400"
|
|
||||||
echo ""
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set content type and CORS headers
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Configuration paths
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/memory_settings.conf"
|
|
||||||
FALLBACK_CONFIG_FILE="/tmp/quecmanager/settings/memory_settings.conf"
|
|
||||||
|
|
||||||
# Get current configuration
|
|
||||||
get_config() {
|
|
||||||
# Defaults
|
|
||||||
ENABLED="false"
|
|
||||||
INTERVAL="1"
|
|
||||||
|
|
||||||
# Try primary config first, then fallback
|
|
||||||
local config_to_read=""
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
config_to_read="$CONFIG_FILE"
|
|
||||||
elif [ -f "$FALLBACK_CONFIG_FILE" ]; then
|
|
||||||
config_to_read="$FALLBACK_CONFIG_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$config_to_read" ]; then
|
|
||||||
local enabled_val=$(grep "^MEMORY_ENABLED=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '"')
|
|
||||||
local interval_val=$(grep "^MEMORY_INTERVAL=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2)
|
|
||||||
|
|
||||||
case "$enabled_val" in
|
|
||||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
|
||||||
*) ENABLED="false" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if echo "$interval_val" | grep -qE '^[0-9]+$' && [ "$interval_val" -ge 1 ] && [ "$interval_val" -le 10 ]; then
|
|
||||||
INTERVAL="$interval_val"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if memory daemon is running
|
|
||||||
is_memory_daemon_running() {
|
|
||||||
pgrep -f "memory_daemon.sh" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle GET request only
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" != "GET" ]; then
|
|
||||||
echo "{\"status\":\"error\",\"code\":\"METHOD_NOT_ALLOWED\",\"message\":\"Only GET method is supported\"}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get current configuration
|
|
||||||
get_config
|
|
||||||
|
|
||||||
# Check daemon status
|
|
||||||
running="false"
|
|
||||||
if is_memory_daemon_running; then
|
|
||||||
running="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return configuration and status
|
|
||||||
echo "{\"status\":\"success\",\"data\":{\"enabled\":$ENABLED,\"interval\":$INTERVAL,\"running\":$running}}"
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Ping Data Fetch Script - Simplified and OpenWrt compatible
|
|
||||||
|
|
||||||
# Always set CORS headers first
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Handle OPTIONS request and exit early
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "{\"status\":\"success\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only handle GET requests
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" != "GET" ]; then
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Method not allowed\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
PING_JSON="/tmp/quecmanager/ping_latency.json"
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/ping_settings.conf"
|
|
||||||
|
|
||||||
# Check if ping data file exists
|
|
||||||
if [ -f "$PING_JSON" ] && [ -r "$PING_JSON" ]; then
|
|
||||||
# Read the file content
|
|
||||||
ping_data=$(cat "$PING_JSON" 2>/dev/null)
|
|
||||||
|
|
||||||
# Check if we got content and it looks like JSON
|
|
||||||
if [ -n "$ping_data" ] && echo "$ping_data" | grep -q '"timestamp"'; then
|
|
||||||
# File exists and has content, return it wrapped in success
|
|
||||||
echo "{\"status\":\"success\",\"data\":$ping_data}"
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Ping data file is empty or corrupted\"}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# No ping file exists - check configuration
|
|
||||||
if [ -f "$CONFIG_FILE" ] && [ -r "$CONFIG_FILE" ]; then
|
|
||||||
# Check if ping monitoring is enabled
|
|
||||||
if grep -q "^PING_ENABLED=true" "$CONFIG_FILE" 2>/dev/null; then
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Ping daemon starting up\"}"
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Ping monitoring disabled\"}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Ping monitoring not configured\"}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always exit cleanly
|
|
||||||
exit 0
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Ping Service Configuration Script - Simple OpenWrt compatible version
|
|
||||||
|
|
||||||
# Always set CORS headers first
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Handle OPTIONS request and exit early
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "{\"status\":\"success\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only handle GET requests
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" != "GET" ]; then
|
|
||||||
echo "{\"status\":\"error\",\"message\":\"Method not allowed\"}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configuration path
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/ping_settings.conf"
|
|
||||||
|
|
||||||
# Get current configuration
|
|
||||||
ENABLED="false"
|
|
||||||
INTERVAL="5"
|
|
||||||
HOST="8.8.8.8"
|
|
||||||
|
|
||||||
if [ -f "$CONFIG_FILE" ] && [ -r "$CONFIG_FILE" ]; then
|
|
||||||
# Parse config using awk (more reliable in BusyBox)
|
|
||||||
enabled_val=$(awk -F'=' '/^PING_ENABLED=/ {print $2}' "$CONFIG_FILE" 2>/dev/null | tr -d '"')
|
|
||||||
interval_val=$(awk -F'=' '/^PING_INTERVAL=/ {print $2}' "$CONFIG_FILE" 2>/dev/null)
|
|
||||||
host_val=$(awk -F'=' '/^PING_HOST=/ {print $2}' "$CONFIG_FILE" 2>/dev/null | tr -d '"')
|
|
||||||
|
|
||||||
case "$enabled_val" in
|
|
||||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
|
||||||
*) ENABLED="false" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if echo "$interval_val" | grep -qE '^[0-9]+$' && [ "$interval_val" -ge 1 ] && [ "$interval_val" -le 3600 ]; then
|
|
||||||
INTERVAL="$interval_val"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$host_val" ]; then
|
|
||||||
HOST="$host_val"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if ping daemon is running
|
|
||||||
RUNNING="false"
|
|
||||||
if pgrep -f "ping_daemon.sh" >/dev/null 2>&1; then
|
|
||||||
RUNNING="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return configuration and status
|
|
||||||
echo "{\"status\":\"success\",\"data\":{\"enabled\":$ENABLED,\"interval\":$INTERVAL,\"host\":\"$HOST\",\"running\":$RUNNING}}"
|
|
||||||
|
|
||||||
# Always exit cleanly
|
|
||||||
exit 0
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Get token from Request Header Authorization
|
|
||||||
USER_TOKEN="${HTTP_AUTHORIZATION}"
|
|
||||||
# Remove token from file
|
|
||||||
sed -i -e "s/.*${USER_TOKEN}.*//g" /tmp/auth_success 2>/dev/null
|
|
||||||
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Cache-Control: no-cache, no-store, must-revalidate"
|
|
||||||
echo "Pragma: no-cache"
|
|
||||||
echo "Expires: 0"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo '{"state":"success", "message":"Logged out successfully"}'
|
|
||||||
@@ -35,15 +35,15 @@ if [ -f "$STATUS_FILE" ]; then
|
|||||||
if [ -s "$STATUS_FILE" ]; then
|
if [ -s "$STATUS_FILE" ]; then
|
||||||
# Cat the entire file content (more reliable than grep)
|
# Cat the entire file content (more reliable than grep)
|
||||||
status_content=$(cat "$STATUS_FILE")
|
status_content=$(cat "$STATUS_FILE")
|
||||||
|
|
||||||
# Log content for debugging
|
# Log content for debugging
|
||||||
log_message "Status file content: $status_content" "debug"
|
log_message "Status file content: $status_content" "debug"
|
||||||
|
|
||||||
# Check if it looks like valid JSON
|
# Check if it looks like valid JSON
|
||||||
if echo "$status_content" | grep -q "status"; then
|
if echo "$status_content" | grep -q "status"; then
|
||||||
# Output the status file content
|
# Output the status file content
|
||||||
cat "$STATUS_FILE"
|
cat "$STATUS_FILE"
|
||||||
|
|
||||||
# Extract status for logging only
|
# Extract status for logging only
|
||||||
status=$(echo "$status_content" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
|
status=$(echo "$status_content" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
|
||||||
log_message "Status from file: $status" "info"
|
log_message "Status from file: $status" "info"
|
||||||
@@ -63,7 +63,7 @@ if [ -f "$TRACK_FILE" ]; then
|
|||||||
status=$(echo "$status_info" | cut -d':' -f1)
|
status=$(echo "$status_info" | cut -d':' -f1)
|
||||||
profile=$(echo "$status_info" | cut -d':' -f2)
|
profile=$(echo "$status_info" | cut -d':' -f2)
|
||||||
progress=$(echo "$status_info" | cut -d':' -f3)
|
progress=$(echo "$status_info" | cut -d':' -f3)
|
||||||
|
|
||||||
# Make sure the message reflects the actual status
|
# Make sure the message reflects the actual status
|
||||||
if [ "$status" = "success" ]; then
|
if [ "$status" = "success" ]; then
|
||||||
message="Profile successfully applied"
|
message="Profile successfully applied"
|
||||||
@@ -76,7 +76,7 @@ if [ -f "$TRACK_FILE" ]; then
|
|||||||
else
|
else
|
||||||
message="Profile operation status: $status"
|
message="Profile operation status: $status"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Output JSON based on track file
|
# Output JSON based on track file
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,35 +34,35 @@ fi
|
|||||||
# Function to extract profiles from UCI config
|
# Function to extract profiles from UCI config
|
||||||
get_profiles() {
|
get_profiles() {
|
||||||
log_message "Fetching profiles from UCI config"
|
log_message "Fetching profiles from UCI config"
|
||||||
|
|
||||||
# Check if UCI config exists
|
# Check if UCI config exists
|
||||||
if [ ! -f /etc/config/quecprofiles ]; then
|
if [ ! -f /etc/config/quecprofiles ]; then
|
||||||
log_message "No profiles config found" "warn"
|
log_message "No profiles config found" "warn"
|
||||||
echo "{\"status\":\"success\",\"profiles\":[]}"
|
echo "{\"status\":\"success\",\"profiles\":[]}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start JSON output
|
# Start JSON output
|
||||||
local json_output=""
|
local json_output=""
|
||||||
local first=1
|
local first=1
|
||||||
local count=0
|
local count=0
|
||||||
|
|
||||||
# Get all profile indices - make sure this succeeds
|
# Get all profile indices - make sure this succeeds
|
||||||
local indices=$(uci -q show quecprofiles | grep -o '@profile\[[0-9]*\]' | sort -u)
|
local indices=$(uci -q show quecprofiles | grep -o '@profile\[[0-9]*\]' | sort -u)
|
||||||
|
|
||||||
# Debug output
|
# Debug output
|
||||||
echo "Found indices: $indices" >>/tmp/list_profiles_error.log
|
echo "Found indices: $indices" >>/tmp/list_profiles_error.log
|
||||||
|
|
||||||
if [ -z "$indices" ]; then
|
if [ -z "$indices" ]; then
|
||||||
log_message "No profile indices found" "warn"
|
log_message "No profile indices found" "warn"
|
||||||
echo "{\"status\":\"success\",\"profiles\":[]}"
|
echo "{\"status\":\"success\",\"profiles\":[]}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Process each profile
|
# Process each profile
|
||||||
for idx in $indices; do
|
for idx in $indices; do
|
||||||
log_message "Processing profile index: $idx"
|
log_message "Processing profile index: $idx"
|
||||||
|
|
||||||
# Try different UCI get approaches
|
# Try different UCI get approaches
|
||||||
local name
|
local name
|
||||||
name=$(uci -q get "quecprofiles.$idx.name" 2>/dev/null)
|
name=$(uci -q get "quecprofiles.$idx.name" 2>/dev/null)
|
||||||
@@ -72,7 +72,7 @@ get_profiles() {
|
|||||||
section=${section%]}
|
section=${section%]}
|
||||||
name=$(uci -q get "quecprofiles.@profile[$section].name" 2>/dev/null)
|
name=$(uci -q get "quecprofiles.@profile[$section].name" 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get profile details
|
# Get profile details
|
||||||
local iccid=$(uci -q get "quecprofiles.$idx.iccid" 2>/dev/null)
|
local iccid=$(uci -q get "quecprofiles.$idx.iccid" 2>/dev/null)
|
||||||
local imei=$(uci -q get "quecprofiles.$idx.imei" 2>/dev/null)
|
local imei=$(uci -q get "quecprofiles.$idx.imei" 2>/dev/null)
|
||||||
@@ -83,9 +83,8 @@ get_profiles() {
|
|||||||
local nsa_nr5g_bands=$(uci -q get "quecprofiles.$idx.nsa_nr5g_bands" 2>/dev/null)
|
local nsa_nr5g_bands=$(uci -q get "quecprofiles.$idx.nsa_nr5g_bands" 2>/dev/null)
|
||||||
local network_type=$(uci -q get "quecprofiles.$idx.network_type" 2>/dev/null)
|
local network_type=$(uci -q get "quecprofiles.$idx.network_type" 2>/dev/null)
|
||||||
local ttl=$(uci -q get "quecprofiles.$idx.ttl" 2>/dev/null)
|
local ttl=$(uci -q get "quecprofiles.$idx.ttl" 2>/dev/null)
|
||||||
local mobile_provider=$(uci -q get "quecprofiles.$idx.mobile_provider" 2>/dev/null)
|
|
||||||
local paused=$(uci -q get "quecprofiles.$idx.paused" 2>/dev/null)
|
local paused=$(uci -q get "quecprofiles.$idx.paused" 2>/dev/null)
|
||||||
|
|
||||||
# Debug output
|
# Debug output
|
||||||
log_message "Retrieved for $idx: name=$name, iccid=$iccid, apn=$apn, paused=$paused"
|
log_message "Retrieved for $idx: name=$name, iccid=$iccid, apn=$apn, paused=$paused"
|
||||||
|
|
||||||
@@ -94,7 +93,7 @@ get_profiles() {
|
|||||||
log_message "Skipping invalid profile: $idx (missing required fields)" "warn"
|
log_message "Skipping invalid profile: $idx (missing required fields)" "warn"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Sanitize all values to ensure valid JSON
|
# Sanitize all values to ensure valid JSON
|
||||||
name=$(sanitize_for_json "$name")
|
name=$(sanitize_for_json "$name")
|
||||||
iccid=$(sanitize_for_json "$iccid")
|
iccid=$(sanitize_for_json "$iccid")
|
||||||
@@ -106,9 +105,8 @@ get_profiles() {
|
|||||||
nsa_nr5g_bands=$(sanitize_for_json "${nsa_nr5g_bands:-""}")
|
nsa_nr5g_bands=$(sanitize_for_json "${nsa_nr5g_bands:-""}")
|
||||||
network_type=$(sanitize_for_json "${network_type:-"LTE"}")
|
network_type=$(sanitize_for_json "${network_type:-"LTE"}")
|
||||||
ttl=$(sanitize_for_json "${ttl:-0}")
|
ttl=$(sanitize_for_json "${ttl:-0}")
|
||||||
mobile_provider=$(sanitize_for_json "${mobile_provider:-""}")
|
|
||||||
paused=$(sanitize_for_json "${paused:-0}")
|
paused=$(sanitize_for_json "${paused:-0}")
|
||||||
|
|
||||||
# Create profile JSON
|
# Create profile JSON
|
||||||
local profile_json="{"
|
local profile_json="{"
|
||||||
profile_json="${profile_json}\"name\":\"${name}\","
|
profile_json="${profile_json}\"name\":\"${name}\","
|
||||||
@@ -121,28 +119,27 @@ get_profiles() {
|
|||||||
profile_json="${profile_json}\"nsa_nr5g_bands\":\"${nsa_nr5g_bands}\","
|
profile_json="${profile_json}\"nsa_nr5g_bands\":\"${nsa_nr5g_bands}\","
|
||||||
profile_json="${profile_json}\"network_type\":\"${network_type}\","
|
profile_json="${profile_json}\"network_type\":\"${network_type}\","
|
||||||
profile_json="${profile_json}\"ttl\":\"${ttl}\","
|
profile_json="${profile_json}\"ttl\":\"${ttl}\","
|
||||||
profile_json="${profile_json}\"mobile_provider\":\"${mobile_provider}\","
|
|
||||||
profile_json="${profile_json}\"paused\":\"${paused}\""
|
profile_json="${profile_json}\"paused\":\"${paused}\""
|
||||||
profile_json="${profile_json}}"
|
profile_json="${profile_json}}"
|
||||||
|
|
||||||
# Add comma if not first
|
# Add comma if not first
|
||||||
if [ $first -eq 0 ]; then
|
if [ $first -eq 0 ]; then
|
||||||
json_output="${json_output},"
|
json_output="${json_output},"
|
||||||
else
|
else
|
||||||
first=0
|
first=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add profile to output
|
# Add profile to output
|
||||||
json_output="${json_output}${profile_json}"
|
json_output="${json_output}${profile_json}"
|
||||||
count=$((count+1))
|
count=$((count+1))
|
||||||
done
|
done
|
||||||
|
|
||||||
# Complete the JSON response
|
# Complete the JSON response
|
||||||
local response="{\"status\":\"success\",\"profiles\":[${json_output}]}"
|
local response="{\"status\":\"success\",\"profiles\":[${json_output}]}"
|
||||||
|
|
||||||
# Save the response for debugging
|
# Save the response for debugging
|
||||||
echo "$response" > /tmp/list_profiles_response.json
|
echo "$response" > /tmp/list_profiles_response.json
|
||||||
|
|
||||||
echo "$response"
|
echo "$response"
|
||||||
log_message "Found and returned $count profiles"
|
log_message "Found and returned $count profiles"
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ create_profile() {
|
|||||||
local nsa_nr5g_bands="$8"
|
local nsa_nr5g_bands="$8"
|
||||||
local network_type="$9"
|
local network_type="$9"
|
||||||
local ttl="${10}"
|
local ttl="${10}"
|
||||||
local mobile_provider="${11}"
|
|
||||||
|
|
||||||
# Generate a unique ID for the profile
|
# Generate a unique ID for the profile
|
||||||
local profile_id="profile_$(date +%s)_$(head -c 4 /dev/urandom | hexdump -e '"%x"')"
|
local profile_id="profile_$(date +%s)_$(head -c 4 /dev/urandom | hexdump -e '"%x"')"
|
||||||
@@ -155,7 +154,6 @@ set quecprofiles.@profile[-1].nsa_nr5g_bands='$nsa_nr5g_bands'
|
|||||||
set quecprofiles.@profile[-1].network_type='$network_type'
|
set quecprofiles.@profile[-1].network_type='$network_type'
|
||||||
set quecprofiles.@profile[-1].ttl='$ttl'
|
set quecprofiles.@profile[-1].ttl='$ttl'
|
||||||
set quecprofiles.@profile[-1].paused='0'
|
set quecprofiles.@profile[-1].paused='0'
|
||||||
set quecprofiles.@profile[-1].mobile_provider='$mobile_provider'
|
|
||||||
commit quecprofiles
|
commit quecprofiles
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -208,7 +206,6 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
|||||||
nsa_nr5g_bands=$(echo "$POST_DATA" | jsonfilter -e '@.nsa_nr5g_bands' 2>/dev/null)
|
nsa_nr5g_bands=$(echo "$POST_DATA" | jsonfilter -e '@.nsa_nr5g_bands' 2>/dev/null)
|
||||||
network_type=$(echo "$POST_DATA" | jsonfilter -e '@.network_type' 2>/dev/null)
|
network_type=$(echo "$POST_DATA" | jsonfilter -e '@.network_type' 2>/dev/null)
|
||||||
ttl=$(echo "$POST_DATA" | jsonfilter -e '@.ttl' 2>/dev/null)
|
ttl=$(echo "$POST_DATA" | jsonfilter -e '@.ttl' 2>/dev/null)
|
||||||
mobile_provider=$(echo "$POST_DATA" | jsonfilter -e '@.mobile_provider' 2>/dev/null)
|
|
||||||
|
|
||||||
log_message "Parsed JSON data for profile: $name" "debug"
|
log_message "Parsed JSON data for profile: $name" "debug"
|
||||||
else
|
else
|
||||||
@@ -224,7 +221,6 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
|||||||
nsa_nr5g_bands=$(echo "$POST_DATA" | grep -o '"nsa_nr5g_bands":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
nsa_nr5g_bands=$(echo "$POST_DATA" | grep -o '"nsa_nr5g_bands":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
network_type=$(echo "$POST_DATA" | grep -o '"network_type":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
network_type=$(echo "$POST_DATA" | grep -o '"network_type":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
ttl=$(echo "$POST_DATA" | grep -o '"ttl":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
ttl=$(echo "$POST_DATA" | grep -o '"ttl":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
mobile_provider=$(echo "$POST_DATA" | grep -o '"mobile_provider":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
|
||||||
|
|
||||||
log_message "Basic parsing for profile: $name" "warn"
|
log_message "Basic parsing for profile: $name" "warn"
|
||||||
fi
|
fi
|
||||||
@@ -244,7 +240,6 @@ else
|
|||||||
nsa_nr5g_bands=$(echo "$QUERY_STRING" | grep -o 'nsa_nr5g_bands=[^&]*' | cut -d'=' -f2)
|
nsa_nr5g_bands=$(echo "$QUERY_STRING" | grep -o 'nsa_nr5g_bands=[^&]*' | cut -d'=' -f2)
|
||||||
network_type=$(echo "$QUERY_STRING" | grep -o 'network_type=[^&]*' | cut -d'=' -f2)
|
network_type=$(echo "$QUERY_STRING" | grep -o 'network_type=[^&]*' | cut -d'=' -f2)
|
||||||
ttl=$(echo "$QUERY_STRING" | grep -o 'ttl=[^&]*' | cut -d'=' -f2)
|
ttl=$(echo "$QUERY_STRING" | grep -o 'ttl=[^&]*' | cut -d'=' -f2)
|
||||||
mobile_provider=$(echo "$QUERY_STRING" | grep -o 'mobile_provider=[^&]*' | cut -d'=' -f2)
|
|
||||||
|
|
||||||
# URL decode values
|
# URL decode values
|
||||||
name=$(echo "$name" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
name=$(echo "$name" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
@@ -257,7 +252,6 @@ else
|
|||||||
nsa_nr5g_bands=$(echo "$nsa_nr5g_bands" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
nsa_nr5g_bands=$(echo "$nsa_nr5g_bands" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
network_type=$(echo "$network_type" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
network_type=$(echo "$network_type" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
ttl=$(echo "$ttl" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
ttl=$(echo "$ttl" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
mobile_provider=$(echo "$mobile_provider" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
|
||||||
|
|
||||||
log_message "Using URL parameters" "warn"
|
log_message "Using URL parameters" "warn"
|
||||||
fi
|
fi
|
||||||
@@ -273,7 +267,6 @@ sa_nr5g_bands=$(sanitize "${sa_nr5g_bands:-}")
|
|||||||
nsa_nr5g_bands=$(sanitize "${nsa_nr5g_bands:-}")
|
nsa_nr5g_bands=$(sanitize "${nsa_nr5g_bands:-}")
|
||||||
network_type=$(sanitize "${network_type:-LTE}")
|
network_type=$(sanitize "${network_type:-LTE}")
|
||||||
ttl=$(sanitize "${ttl:-0}") # Default to 0 (disabled)
|
ttl=$(sanitize "${ttl:-0}") # Default to 0 (disabled)
|
||||||
mobile_provider=$(sanitize "${mobile_provider:-Other}")
|
|
||||||
|
|
||||||
# Output debug info
|
# Output debug info
|
||||||
log_message "Creating profile: $name, ICCID: $iccid, IMEI: $imei, APN: $apn" "debug"
|
log_message "Creating profile: $name, ICCID: $iccid, IMEI: $imei, APN: $apn" "debug"
|
||||||
@@ -347,14 +340,14 @@ elif [ $dup_status -eq 2 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Create the profile
|
# Create the profile
|
||||||
if create_profile "$name" "$iccid" "$imei" "$apn" "$pdp_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" "$network_type" "$ttl" "$mobile_provider"; then
|
if create_profile "$name" "$iccid" "$imei" "$apn" "$pdp_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" "$network_type" "$ttl"; then
|
||||||
# Trigger immediate profile application
|
# Trigger immediate profile application
|
||||||
touch "/tmp/quecprofiles_check"
|
touch "/tmp/quecprofiles_check"
|
||||||
chmod 644 "/tmp/quecprofiles_check"
|
chmod 644 "/tmp/quecprofiles_check"
|
||||||
log_message "Triggered immediate profile check after creation" "info"
|
log_message "Triggered immediate profile check after creation" "info"
|
||||||
|
|
||||||
# Create profile data JSON for return - WITHOUT outer curly braces
|
# Create profile data JSON for return - WITHOUT outer curly braces
|
||||||
profile_data="\"name\":\"$name\",\"iccid\":\"$iccid\",\"imei\":\"$imei\",\"apn\":\"$apn\",\"pdp_type\":\"$pdp_type\",\"lte_bands\":\"$lte_bands\",\"sa_nr5g_bands\":\"$sa_nr5g_bands\",\"nsa_nr5g_bands\":\"$nsa_nr5g_bands\",\"network_type\":\"$network_type\",\"ttl\":\"$ttl\",\"mobile_provider\":\"$mobile_provider\""
|
profile_data="\"name\":\"$name\",\"iccid\":\"$iccid\",\"imei\":\"$imei\",\"apn\":\"$apn\",\"pdp_type\":\"$pdp_type\",\"lte_bands\":\"$lte_bands\",\"sa_nr5g_bands\":\"$sa_nr5g_bands\",\"nsa_nr5g_bands\":\"$nsa_nr5g_bands\",\"network_type\":\"$network_type\",\"ttl\":\"$ttl\""
|
||||||
|
|
||||||
# Wrap the data field in curly braces inside output_json
|
# Wrap the data field in curly braces inside output_json
|
||||||
output_json "success" "Profile created successfully" "{$profile_data}"
|
output_json "success" "Profile created successfully" "{$profile_data}"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ output_json() {
|
|||||||
local status="$1"
|
local status="$1"
|
||||||
local message="$2"
|
local message="$2"
|
||||||
local data="${3:-{}}"
|
local data="${3:-{}}"
|
||||||
|
|
||||||
printf '{"status":"%s","message":"%s","data":%s}\n' "$status" "$message" "$data"
|
printf '{"status":"%s","message":"%s","data":%s}\n' "$status" "$message" "$data"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ find_profile_by_iccid() {
|
|||||||
local iccid="$1"
|
local iccid="$1"
|
||||||
# Get all profile indices
|
# Get all profile indices
|
||||||
local profile_indices=$(uci show quecprofiles | grep -o '@profile\[[0-9]\+\]' | sort -u)
|
local profile_indices=$(uci show quecprofiles | grep -o '@profile\[[0-9]\+\]' | sort -u)
|
||||||
|
|
||||||
for profile_index in $profile_indices; do
|
for profile_index in $profile_indices; do
|
||||||
local current_iccid=$(uci -q get quecprofiles.$profile_index.iccid)
|
local current_iccid=$(uci -q get quecprofiles.$profile_index.iccid)
|
||||||
if [ "$current_iccid" = "$iccid" ]; then
|
if [ "$current_iccid" = "$iccid" ]; then
|
||||||
@@ -40,7 +40,7 @@ find_profile_by_iccid() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,13 +48,13 @@ find_profile_by_iccid() {
|
|||||||
delete_profile() {
|
delete_profile() {
|
||||||
local profile_index="$1"
|
local profile_index="$1"
|
||||||
local profile_name=$(uci -q get quecprofiles.$profile_index.name)
|
local profile_name=$(uci -q get quecprofiles.$profile_index.name)
|
||||||
|
|
||||||
# Delete the profile from UCI config
|
# Delete the profile from UCI config
|
||||||
uci -q batch <<EOF
|
uci -q batch <<EOF
|
||||||
delete quecprofiles.$profile_index
|
delete quecprofiles.$profile_index
|
||||||
commit quecprofiles
|
commit quecprofiles
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Check if the operation was successful
|
# Check if the operation was successful
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
log_message "Successfully deleted profile '$profile_name'" "info"
|
log_message "Successfully deleted profile '$profile_name'" "info"
|
||||||
@@ -80,14 +80,14 @@ iccid=""
|
|||||||
if [ "$REQUEST_METHOD" = "POST" ]; then
|
if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||||
# Get content length
|
# Get content length
|
||||||
CONTENT_LENGTH=$(echo "$CONTENT_LENGTH" | tr -cd '0-9')
|
CONTENT_LENGTH=$(echo "$CONTENT_LENGTH" | tr -cd '0-9')
|
||||||
|
|
||||||
if [ -n "$CONTENT_LENGTH" ]; then
|
if [ -n "$CONTENT_LENGTH" ]; then
|
||||||
# Read POST data
|
# Read POST data
|
||||||
POST_DATA=$(dd bs=1 count=$CONTENT_LENGTH 2>/dev/null)
|
POST_DATA=$(dd bs=1 count=$CONTENT_LENGTH 2>/dev/null)
|
||||||
|
|
||||||
# Debug log
|
# Debug log
|
||||||
log_message "Received POST data: $POST_DATA" "debug"
|
log_message "Received POST data: $POST_DATA" "debug"
|
||||||
|
|
||||||
# Parse JSON with jsonfilter if available
|
# Parse JSON with jsonfilter if available
|
||||||
if command -v jsonfilter >/dev/null 2>&1; then
|
if command -v jsonfilter >/dev/null 2>&1; then
|
||||||
iccid=$(echo "$POST_DATA" | jsonfilter -e '@.iccid' 2>/dev/null)
|
iccid=$(echo "$POST_DATA" | jsonfilter -e '@.iccid' 2>/dev/null)
|
||||||
@@ -102,10 +102,10 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
|||||||
elif [ -n "$QUERY_STRING" ]; then
|
elif [ -n "$QUERY_STRING" ]; then
|
||||||
# URL parameters for GET or DELETE requests
|
# URL parameters for GET or DELETE requests
|
||||||
iccid=$(echo "$QUERY_STRING" | grep -o 'iccid=[^&]*' | cut -d'=' -f2)
|
iccid=$(echo "$QUERY_STRING" | grep -o 'iccid=[^&]*' | cut -d'=' -f2)
|
||||||
|
|
||||||
# URL decode value
|
# URL decode value
|
||||||
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
|
|
||||||
log_message "Using URL parameter: iccid=$iccid" "debug"
|
log_message "Using URL parameter: iccid=$iccid" "debug"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ update_profile() {
|
|||||||
local nsa_nr5g_bands="$8"
|
local nsa_nr5g_bands="$8"
|
||||||
local network_type="$9"
|
local network_type="$9"
|
||||||
local ttl="${10}"
|
local ttl="${10}"
|
||||||
local mobile_provider="${11}"
|
|
||||||
|
|
||||||
# Update the profile in UCI config
|
# Update the profile in UCI config
|
||||||
uci -q batch <<EOF
|
uci -q batch <<EOF
|
||||||
@@ -184,7 +183,6 @@ set quecprofiles.$profile_index.sa_nr5g_bands='$sa_nr5g_bands'
|
|||||||
set quecprofiles.$profile_index.nsa_nr5g_bands='$nsa_nr5g_bands'
|
set quecprofiles.$profile_index.nsa_nr5g_bands='$nsa_nr5g_bands'
|
||||||
set quecprofiles.$profile_index.network_type='$network_type'
|
set quecprofiles.$profile_index.network_type='$network_type'
|
||||||
set quecprofiles.$profile_index.ttl='$ttl'
|
set quecprofiles.$profile_index.ttl='$ttl'
|
||||||
set quecprofiles.$profile_index.mobile_provider='$mobile_provider'
|
|
||||||
commit quecprofiles
|
commit quecprofiles
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -239,7 +237,6 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
|||||||
nsa_nr5g_bands=$(echo "$POST_DATA" | jsonfilter -e '@.nsa_nr5g_bands' 2>/dev/null)
|
nsa_nr5g_bands=$(echo "$POST_DATA" | jsonfilter -e '@.nsa_nr5g_bands' 2>/dev/null)
|
||||||
network_type=$(echo "$POST_DATA" | jsonfilter -e '@.network_type' 2>/dev/null)
|
network_type=$(echo "$POST_DATA" | jsonfilter -e '@.network_type' 2>/dev/null)
|
||||||
ttl=$(echo "$POST_DATA" | jsonfilter -e '@.ttl' 2>/dev/null)
|
ttl=$(echo "$POST_DATA" | jsonfilter -e '@.ttl' 2>/dev/null)
|
||||||
mobile_provider=$(echo "$POST_DATA" | jsonfilter -e '@.mobile_provider' 2>/dev/null)
|
|
||||||
|
|
||||||
log_message "Parsed JSON data for profile: $name" "debug"
|
log_message "Parsed JSON data for profile: $name" "debug"
|
||||||
else
|
else
|
||||||
@@ -255,7 +252,6 @@ if [ "$REQUEST_METHOD" = "POST" ]; then
|
|||||||
nsa_nr5g_bands=$(echo "$POST_DATA" | grep -o '"nsa_nr5g_bands":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
nsa_nr5g_bands=$(echo "$POST_DATA" | grep -o '"nsa_nr5g_bands":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
network_type=$(echo "$POST_DATA" | grep -o '"network_type":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
network_type=$(echo "$POST_DATA" | grep -o '"network_type":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
ttl=$(echo "$POST_DATA" | grep -o '"ttl":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
ttl=$(echo "$POST_DATA" | grep -o '"ttl":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
||||||
mobile_provider=$(echo "$POST_DATA" | grep -o '"mobile_provider":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"')
|
|
||||||
|
|
||||||
log_message "Basic parsing for profile: $name" "warn"
|
log_message "Basic parsing for profile: $name" "warn"
|
||||||
fi
|
fi
|
||||||
@@ -275,7 +271,6 @@ else
|
|||||||
nsa_nr5g_bands=$(echo "$QUERY_STRING" | grep -o 'nsa_nr5g_bands=[^&]*' | cut -d'=' -f2)
|
nsa_nr5g_bands=$(echo "$QUERY_STRING" | grep -o 'nsa_nr5g_bands=[^&]*' | cut -d'=' -f2)
|
||||||
network_type=$(echo "$QUERY_STRING" | grep -o 'network_type=[^&]*' | cut -d'=' -f2)
|
network_type=$(echo "$QUERY_STRING" | grep -o 'network_type=[^&]*' | cut -d'=' -f2)
|
||||||
ttl=$(echo "$QUERY_STRING" | grep -o 'ttl=[^&]*' | cut -d'=' -f2)
|
ttl=$(echo "$QUERY_STRING" | grep -o 'ttl=[^&]*' | cut -d'=' -f2)
|
||||||
mobile_provider=$(echo "$QUERY_STRING" | grep -o 'mobile_provider=[^&]*' | cut -d'=' -f2)
|
|
||||||
|
|
||||||
# URL decode values
|
# URL decode values
|
||||||
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
@@ -288,7 +283,6 @@ else
|
|||||||
nsa_nr5g_bands=$(echo "$nsa_nr5g_bands" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
nsa_nr5g_bands=$(echo "$nsa_nr5g_bands" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
network_type=$(echo "$network_type" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
network_type=$(echo "$network_type" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
ttl=$(echo "$ttl" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
ttl=$(echo "$ttl" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
mobile_provider=$(echo "$mobile_provider" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
|
||||||
|
|
||||||
log_message "Using URL parameters" "warn"
|
log_message "Using URL parameters" "warn"
|
||||||
fi
|
fi
|
||||||
@@ -304,7 +298,6 @@ sa_nr5g_bands=$(sanitize "${sa_nr5g_bands:-}")
|
|||||||
nsa_nr5g_bands=$(sanitize "${nsa_nr5g_bands:-}")
|
nsa_nr5g_bands=$(sanitize "${nsa_nr5g_bands:-}")
|
||||||
network_type=$(sanitize "${network_type:-LTE}")
|
network_type=$(sanitize "${network_type:-LTE}")
|
||||||
ttl=$(sanitize "${ttl:-0}") # Default to 0 (disabled)
|
ttl=$(sanitize "${ttl:-0}") # Default to 0 (disabled)
|
||||||
mobile_provider=$(sanitize "${mobile_provider:-Other}")
|
|
||||||
|
|
||||||
# Output debug info
|
# Output debug info
|
||||||
log_message "Editing profile: $name, ICCID: $iccid, IMEI: $imei, APN: $apn" "debug"
|
log_message "Editing profile: $name, ICCID: $iccid, IMEI: $imei, APN: $apn" "debug"
|
||||||
@@ -380,18 +373,18 @@ if check_duplicate_name "$name" "$iccid"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Update profile
|
# Update profile
|
||||||
if update_profile "$profile_index" "$name" "$imei" "$apn" "$pdp_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" "$network_type" "$ttl" "$mobile_provider"; then
|
if update_profile "$profile_index" "$name" "$imei" "$apn" "$pdp_type" "$lte_bands" "$nr5g_bands" "$network_type"; then
|
||||||
# Trigger immediate profile application
|
# Trigger immediate profile application
|
||||||
touch "/tmp/quecprofiles_check"
|
touch "/tmp/quecprofiles_check"
|
||||||
chmod 644 "/tmp/quecprofiles_check"
|
chmod 644 "/tmp/quecprofiles_check"
|
||||||
log_message "Triggered immediate profile check after update" "info"
|
log_message "Triggered immediate profile check after update" "info"
|
||||||
|
|
||||||
# Create a clean JSON response with properly escaped quotes
|
# Create a clean JSON response with properly escaped quotes
|
||||||
printf '{"status":"success","message":"Profile updated successfully","data":{"name":"%s","iccid":"%s","imei":"%s","apn":"%s","pdp_type":"%s","lte_bands":"%s","nr5g_bands":"%s","network_type":"%s"}}' \
|
printf '{"status":"success","message":"Profile updated successfully","data":{"name":"%s","iccid":"%s","imei":"%s","apn":"%s","pdp_type":"%s","lte_bands":"%s","nr5g_bands":"%s","network_type":"%s"}}' \
|
||||||
"$name" "$iccid" "$imei" "$apn" "$pdp_type" "$lte_bands" "$nr5g_bands" "$network_type"
|
"$name" "$iccid" "$imei" "$apn" "$pdp_type" "$lte_bands" "$nr5g_bands" "$network_type"
|
||||||
|
|
||||||
log_message "Profile updated successfully: $name" "info"
|
log_message "Profile updated successfully: $name" "info"
|
||||||
|
|
||||||
# Note: The conditional trigger is replaced with the direct trigger above
|
# Note: The conditional trigger is replaced with the direct trigger above
|
||||||
else
|
else
|
||||||
printf '{"status":"error","message":"Failed to update profile. Please check system logs."}'
|
printf '{"status":"error","message":"Failed to update profile. Please check system logs."}'
|
||||||
|
|||||||
@@ -145,10 +145,10 @@ elif [ -n "$QUERY_STRING" ]; then
|
|||||||
# URL parameters for GET requests (for testing)
|
# URL parameters for GET requests (for testing)
|
||||||
iccid=$(echo "$QUERY_STRING" | grep -o 'iccid=[^&]*' | cut -d'=' -f2)
|
iccid=$(echo "$QUERY_STRING" | grep -o 'iccid=[^&]*' | cut -d'=' -f2)
|
||||||
paused=$(echo "$QUERY_STRING" | grep -o 'paused=[^&]*' | cut -d'=' -f2)
|
paused=$(echo "$QUERY_STRING" | grep -o 'paused=[^&]*' | cut -d'=' -f2)
|
||||||
|
|
||||||
# URL decode values
|
# URL decode values
|
||||||
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
iccid=$(echo "$iccid" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' | xargs -0 printf "%b")
|
||||||
|
|
||||||
log_message "Using URL parameters: iccid=$iccid, paused=$paused" "debug"
|
log_message "Using URL parameters: iccid=$iccid, paused=$paused" "debug"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
DEBUG_LOG="/tmp/socat-at-bridge-reset.log"
|
|
||||||
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Cache-Control: no-cache, no-store, must-revalidate"
|
|
||||||
echo "Pragma: no-cache"
|
|
||||||
echo "Expires: 0"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
service socat-at-bridge restart &>/dev/null
|
|
||||||
SOCAT_RESET_STATUS=$?
|
|
||||||
|
|
||||||
touch $DEBUG_LOG
|
|
||||||
# Log the reset status
|
|
||||||
if [ $SOCAT_RESET_STATUS -eq 0 ]; then
|
|
||||||
echo "$(date) - socat-at-bridge service restarted successfully." >> $DEBUG_LOG
|
|
||||||
else
|
|
||||||
echo "$(date) - Failed to restart socat-at-bridge service. Status: $SOCAT_RESET_STATUS" >> $DEBUG_LOG
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Basic response indicating the server is up
|
|
||||||
echo "{\"status\": \"$SOCAT_RESET_STATUS\"}"
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Set Content-Type for CGI script
|
|
||||||
echo "Content-type: application/json"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
TOKEN="${HTTP_AUTHORIZATION}"
|
|
||||||
|
|
||||||
# Read POST data
|
|
||||||
read -r POST_DATA
|
|
||||||
|
|
||||||
# Debug log for generated hash
|
|
||||||
DEBUG_LOG="/tmp/password_change.log"
|
|
||||||
AUTH_FILE="/tmp/auth_success"
|
|
||||||
|
|
||||||
# Get Token from Authorization Header on Request
|
|
||||||
if [ ! -f $AUTH_FILE ]; then
|
|
||||||
echo "{\"error\":\"Unauthenticated Request\"}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$TOKEN" ] || "${TOKEN}" = "" || [ $(grep "${TOKEN}" "${AUTH_FILE}" | wc -l) -eq 0 ]; then
|
|
||||||
echo "{\"response\": { \"status\": \"error\", \"raw_output\": \"Not Authorized\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Not Authorized\"}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if token is within 2 hours
|
|
||||||
TOKEN_LINE=$(grep "${TOKEN}" "${AUTH_FILE}")
|
|
||||||
TOKEN_DATE=$(echo "$TOKEN_LINE" | awk '{print $1}' | sed 's/T/ /')
|
|
||||||
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
|
|
||||||
NOW_TIME=$(date +%s)
|
|
||||||
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
|
|
||||||
|
|
||||||
if [ -z "$TOKEN_TIME" ] || [ $((NOW_TIME - TOKEN_TIME)) -gt $MAX_AGE ]; then
|
|
||||||
echo "{ \"response\": { \"status\": \"error\", \"raw_output\": \"Token expired. Reauthenticate to get new token.\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Token expired\"}"
|
|
||||||
# Cleanup/Remove token from file
|
|
||||||
sed -i -e "s/.*${TOKEN}.*//g" /tmp/auth_success 2>/dev/null
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Extract the passwords from POST data (URL encoded)
|
|
||||||
USER="root"
|
|
||||||
OLD_PASSWORD=$(echo "$POST_DATA" | grep -o 'oldPassword=[^&]*' | cut -d= -f2-)
|
|
||||||
NEW_PASSWORD=$(echo "$POST_DATA" | grep -o 'newPassword=[^&]*' | cut -d= -f2-)
|
|
||||||
|
|
||||||
# URL-decode the passwords (replace + with space and decode %XX)
|
|
||||||
urldecode() {
|
|
||||||
local encoded="${1//+/ }"
|
|
||||||
printf '%b' "${encoded//%/\\x}"
|
|
||||||
}
|
|
||||||
|
|
||||||
OLD_PASSWORD=$(urldecode "$OLD_PASSWORD")
|
|
||||||
NEW_PASSWORD=$(urldecode "$NEW_PASSWORD")
|
|
||||||
|
|
||||||
# Basic validation to reject & and $ characters
|
|
||||||
if echo "$OLD_PASSWORD$NEW_PASSWORD" | grep -q '[&$]'; then
|
|
||||||
echo '{"state":"failed","message":"Password contains forbidden characters (& or $)"}'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract the hashed password from /etc/shadow for the specified user
|
|
||||||
USER_SHADOW_ENTRY=$(grep "^$USER:" /etc/shadow)
|
|
||||||
|
|
||||||
if [ -z "$USER_SHADOW_ENTRY" ]; then
|
|
||||||
echo '{"state":"failed","message":"User not found"}'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract the password hash (second field, colon-separated)
|
|
||||||
USER_HASH=$(echo "$USER_SHADOW_ENTRY" | cut -d: -f2)
|
|
||||||
|
|
||||||
# Extract the salt (MD5 uses the $1$ prefix followed by the salt)
|
|
||||||
SALT=$(echo "$USER_HASH" | cut -d'$' -f3)
|
|
||||||
|
|
||||||
# Generate hash from old password using the same salt
|
|
||||||
OLD_GENERATED_HASH=$(printf '%s' "$OLD_PASSWORD" | openssl passwd -1 -salt "$SALT" -stdin)
|
|
||||||
|
|
||||||
# Verify old password
|
|
||||||
if [ "$OLD_GENERATED_HASH" != "$USER_HASH" ]; then
|
|
||||||
echo '{"state":"failed","message":"Current password is incorrect"}'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a temporary file for the new password
|
|
||||||
PASS_FILE=$(mktemp)
|
|
||||||
chmod 600 "$PASS_FILE"
|
|
||||||
|
|
||||||
# Write the new password twice (for confirmation)
|
|
||||||
printf '%s\n%s\n' "$NEW_PASSWORD" "$NEW_PASSWORD" > "$PASS_FILE"
|
|
||||||
|
|
||||||
# Change password using passwd command
|
|
||||||
ERROR_OUTPUT=$(passwd "$USER" < "$PASS_FILE" 2>&1)
|
|
||||||
RESULT=$?
|
|
||||||
|
|
||||||
# Log the operation
|
|
||||||
echo "Password change attempt. Result: $RESULT. Time: $(date)" >> "$DEBUG_LOG"
|
|
||||||
if [ $RESULT -ne 0 ]; then
|
|
||||||
echo "Error output: $ERROR_OUTPUT" >> "$DEBUG_LOG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
rm -f "$PASS_FILE"
|
|
||||||
|
|
||||||
# Return result
|
|
||||||
if [ $RESULT -eq 0 ]; then
|
|
||||||
echo '{"state":"success","message":"Password changed successfully"}'
|
|
||||||
else
|
|
||||||
echo '{"state":"failed","message":"Failed to change password"}'
|
|
||||||
fi
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Send CGI headers first
|
|
||||||
echo "Content-Type: application/json"
|
|
||||||
echo "Cache-Control: no-cache"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Simple script to force a reboot of the system
|
|
||||||
output_json() {
|
|
||||||
local status="$1"
|
|
||||||
local message="$2"
|
|
||||||
echo "{\"status\": \"$status\", \"message\": \"$message\"}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to force reboot
|
|
||||||
force_reboot() {
|
|
||||||
if command -v reboot >/dev/null 2>&1; then
|
|
||||||
reboot
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
main() {
|
|
||||||
if force_reboot; then
|
|
||||||
output_json "success" "System is rebooting"
|
|
||||||
else
|
|
||||||
output_json "error" "Reboot command not found or failed"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Smart Measurement Units Configuration Script
|
|
||||||
# Manages distance unit preferences (km/mi) with automatic timezone-based defaults
|
|
||||||
# Author: dr-dolomite
|
|
||||||
# Date: 2025-08-04
|
|
||||||
|
|
||||||
# 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/measurement_units.conf"
|
|
||||||
LOG_FILE="/tmp/measurement_units.log"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
log_message "Creating directory: $CONFIG_DIR"
|
|
||||||
mkdir -p "$CONFIG_DIR"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# Try to use a fallback location in /tmp
|
|
||||||
CONFIG_DIR="/tmp/quecmanager/settings"
|
|
||||||
CONFIG_FILE="$CONFIG_DIR/measurement_units.conf"
|
|
||||||
log_message "Fallback to alternative location: $CONFIG_DIR"
|
|
||||||
mkdir -p "$CONFIG_DIR"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
send_error "DIRECTORY_ERROR" "Failed to create configuration directory"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
chmod 755 "$CONFIG_DIR"
|
|
||||||
log_message "Created configuration directory: $CONFIG_DIR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if the country uses imperial or metric system based on timezone
|
|
||||||
get_default_unit() {
|
|
||||||
# Get timezone from OpenWrt system - use uci as primary method
|
|
||||||
local timezone=""
|
|
||||||
|
|
||||||
# Primary method: Use uci command (standard OpenWrt way)
|
|
||||||
if command -v uci >/dev/null 2>&1; then
|
|
||||||
timezone=$(uci -q get system.@system[0].zonename)
|
|
||||||
if [ -z "$timezone" ]; then
|
|
||||||
timezone=$(uci -q get system.@system[0].timezone)
|
|
||||||
fi
|
|
||||||
log_message "Detected timezone using uci command: $timezone"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback method: Parse OpenWrt config file directly
|
|
||||||
if [ -z "$timezone" ] && [ -f "/etc/config/system" ]; then
|
|
||||||
timezone=$(grep -o "option zonename '[^']*'" /etc/config/system | sed "s/option zonename '//;s/'//")
|
|
||||||
|
|
||||||
if [ -z "$timezone" ]; then
|
|
||||||
timezone=$(grep -o "option timezone '[^']*'" /etc/config/system | sed "s/option timezone '//;s/'//")
|
|
||||||
fi
|
|
||||||
log_message "Detected timezone from OpenWrt config file: $timezone"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Additional fallback methods
|
|
||||||
if [ -z "$timezone" ]; then
|
|
||||||
# Try TZ environment variable
|
|
||||||
if [ -n "$TZ" ]; then
|
|
||||||
timezone="$TZ"
|
|
||||||
log_message "Detected timezone from TZ environment variable: $timezone"
|
|
||||||
# Try /etc/TZ file
|
|
||||||
elif [ -f "/etc/TZ" ]; then
|
|
||||||
timezone=$(cat /etc/TZ)
|
|
||||||
log_message "Detected timezone from /etc/TZ file: $timezone"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If still no timezone, use a default
|
|
||||||
if [ -z "$timezone" ]; then
|
|
||||||
timezone="Unknown"
|
|
||||||
log_message "Warning: Could not detect timezone, using default (km)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Countries and territories that primarily use imperial system (miles)
|
|
||||||
# Based on current usage as of 2025:
|
|
||||||
# - United States (including territories)
|
|
||||||
# - Liberia
|
|
||||||
# - Myanmar/Burma (mixed usage, but officially imperial for distances)
|
|
||||||
# - UK uses miles for road distances (though metric for most other measurements)
|
|
||||||
# - Some British territories and dependencies
|
|
||||||
case "$timezone" in
|
|
||||||
# United States and territories - comprehensive timezone coverage
|
|
||||||
*America/New_York*|*America/Chicago*|*America/Denver*|*America/Los_Angeles*|*America/Phoenix*|*America/Anchorage*|*America/Honolulu*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US major cities)"
|
|
||||||
;;
|
|
||||||
# All Americas timezones that are US-based
|
|
||||||
*America/Adak*|*America/Juneau*|*America/Metlakatla*|*America/Nome*|*America/Sitka*|*America/Yakutat*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US Alaska)"
|
|
||||||
;;
|
|
||||||
# US territories in Pacific
|
|
||||||
*Pacific/Honolulu*|*Pacific/Johnston*|*Pacific/Midway*|*Pacific/Wake*|*HST*|*Pacific/Samoa*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US Pacific territories)"
|
|
||||||
;;
|
|
||||||
# US territories in other regions
|
|
||||||
*America/Puerto_Rico*|*America/Virgin*|*Atlantic/Bermuda*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US territories)"
|
|
||||||
;;
|
|
||||||
# General US timezone patterns
|
|
||||||
*America/*EDT*|*America/*EST*|*America/*CDT*|*America/*CST*|*America/*MDT*|*America/*MST*|*America/*PDT*|*America/*PST*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US timezone abbreviations)"
|
|
||||||
;;
|
|
||||||
# Simple timezone abbreviations commonly used in US systems
|
|
||||||
*EST*|*CST*|*MST*|*PST*|*EDT*|*CDT*|*MDT*|*PDT*|*AKST*|*AKDT*|*HST*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (US timezone codes)"
|
|
||||||
;;
|
|
||||||
# United Kingdom - uses miles for road distances
|
|
||||||
*Europe/London*|*GMT*|*BST*|*Europe/Belfast*|*Europe/Edinburgh*|*Europe/Cardiff*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (UK)"
|
|
||||||
;;
|
|
||||||
# British territories and dependencies that use miles
|
|
||||||
*Atlantic/Stanley*|*Indian/Chagos*|*Europe/Gibraltar*|*Atlantic/South_Georgia*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (British territories)"
|
|
||||||
;;
|
|
||||||
# Liberia
|
|
||||||
*Africa/Monrovia*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (Liberia)"
|
|
||||||
;;
|
|
||||||
# Myanmar/Burma (mixed usage but officially uses imperial for some measurements)
|
|
||||||
*Asia/Yangon*|*Asia/Rangoon*)
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (Myanmar)"
|
|
||||||
;;
|
|
||||||
# OpenWrt config format with spaces (common in some router configurations)
|
|
||||||
"America/New York"|"America/Los Angeles"|"America/Chicago"|"America/Denver"|"America/Phoenix"|"America/Anchorage"|"Europe/London")
|
|
||||||
echo "mi"
|
|
||||||
log_message "Default unit based on timezone ($timezone): miles (space-separated format)"
|
|
||||||
;;
|
|
||||||
# Default to metric for all other countries/territories
|
|
||||||
*)
|
|
||||||
echo "km"
|
|
||||||
log_message "Default unit based on timezone ($timezone): kilometers (metric country)"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get current measurement unit
|
|
||||||
get_measurement_unit() {
|
|
||||||
# If config file exists, read from it
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
unit=$(grep "^DISTANCE_UNIT=" "$CONFIG_FILE" | cut -d'=' -f2)
|
|
||||||
if [ -n "$unit" ]; then
|
|
||||||
echo "$unit"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If no config or empty config, determine default based on timezone
|
|
||||||
get_default_unit
|
|
||||||
}
|
|
||||||
|
|
||||||
# Save measurement unit to config file
|
|
||||||
save_measurement_unit() {
|
|
||||||
local unit="$1"
|
|
||||||
ensure_config_directory
|
|
||||||
|
|
||||||
# Create or update config file
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
# Update existing file
|
|
||||||
sed -i "s/^DISTANCE_UNIT=.*$/DISTANCE_UNIT=$unit/" "$CONFIG_FILE"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
# If sed fails (e.g., no match), append the setting
|
|
||||||
echo "DISTANCE_UNIT=$unit" >> "$CONFIG_FILE"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Create new file
|
|
||||||
echo "DISTANCE_UNIT=$unit" > "$CONFIG_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
chmod 644 "$CONFIG_FILE"
|
|
||||||
log_message "Saved distance unit: $unit"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete measurement unit configuration
|
|
||||||
delete_measurement_unit() {
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
# Remove the DISTANCE_UNIT line
|
|
||||||
sed -i '/^DISTANCE_UNIT=/d' "$CONFIG_FILE"
|
|
||||||
log_message "Deleted distance unit configuration"
|
|
||||||
|
|
||||||
# If file is empty after deletion, remove it
|
|
||||||
if [ ! -s "$CONFIG_FILE" ]; then
|
|
||||||
rm -f "$CONFIG_FILE"
|
|
||||||
log_message "Removed empty config file"
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle GET request - Retrieve measurement unit preference
|
|
||||||
handle_get() {
|
|
||||||
log_message "GET request received"
|
|
||||||
|
|
||||||
# Check if this is a debug request
|
|
||||||
if echo "$QUERY_STRING" | grep -q "debug=1"; then
|
|
||||||
# Return diagnostic information
|
|
||||||
local timezone_info=""
|
|
||||||
|
|
||||||
if command -v uci >/dev/null 2>&1; then
|
|
||||||
timezone_info="$timezone_info\"uci_system_zonename\": \"$(uci -q get system.@system[0].zonename || echo 'Not found')\","
|
|
||||||
timezone_info="$timezone_info\"uci_system_timezone\": \"$(uci -q get system.@system[0].timezone || echo 'Not found')\","
|
|
||||||
else
|
|
||||||
timezone_info="$timezone_info\"uci\": \"Command not found\","
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "/etc/config/system" ]; then
|
|
||||||
timezone_info="$timezone_info\"openwrt_config\": \"$(cat /etc/config/system | grep -E 'zonename|timezone' | tr '\n' ' ' | sed 's/"/\\"/g')\","
|
|
||||||
else
|
|
||||||
timezone_info="$timezone_info\"openwrt_config\": \"Not found\","
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$TZ" ]; then
|
|
||||||
timezone_info="$timezone_info\"TZ_env\": \"$TZ\","
|
|
||||||
else
|
|
||||||
timezone_info="$timezone_info\"TZ_env\": \"Not set\","
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "/etc/TZ" ]; then
|
|
||||||
timezone_info="$timezone_info\"etc_TZ\": \"$(cat /etc/TZ)\","
|
|
||||||
else
|
|
||||||
timezone_info="$timezone_info\"etc_TZ\": \"Not found\","
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get default unit
|
|
||||||
local default_unit=$(get_default_unit)
|
|
||||||
|
|
||||||
# Remove trailing comma
|
|
||||||
timezone_info=$(echo "$timezone_info" | sed 's/,$//')
|
|
||||||
|
|
||||||
send_success "Debug information" "{$timezone_info, \"default_unit\": \"$default_unit\"}"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get current unit (from config or default)
|
|
||||||
local unit=$(get_measurement_unit)
|
|
||||||
|
|
||||||
# Check if it's from config or default
|
|
||||||
local is_default=true
|
|
||||||
if [ -f "$CONFIG_FILE" ] && grep -q "^DISTANCE_UNIT=" "$CONFIG_FILE"; then
|
|
||||||
is_default=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
send_success "Measurement unit retrieved" "{\"unit\":\"$unit\",\"isDefault\":$is_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle POST request - Update measurement unit preference
|
|
||||||
handle_post() {
|
|
||||||
log_message "POST request received"
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
log_message "Received POST data: $post_data"
|
|
||||||
|
|
||||||
# Multiple approaches to parse JSON, for robustness across various OpenWrt versions
|
|
||||||
# Approach 1: Simple regex extraction
|
|
||||||
local unit=$(echo "$post_data" | sed -n 's/.*"unit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
||||||
|
|
||||||
# Approach 2: grep + cut extraction
|
|
||||||
if [ -z "$unit" ]; then
|
|
||||||
unit=$(echo "$post_data" | grep -o '"unit":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Approach 3: Very basic extraction - look for km or mi in the payload
|
|
||||||
if [ -z "$unit" ]; then
|
|
||||||
if echo "$post_data" | grep -q '"km"'; then
|
|
||||||
unit="km"
|
|
||||||
elif echo "$post_data" | grep -q '"mi"'; then
|
|
||||||
unit="mi"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_message "Received unit: $unit"
|
|
||||||
|
|
||||||
# Validate unit
|
|
||||||
if [ "$unit" = "km" ] || [ "$unit" = "mi" ]; then
|
|
||||||
save_measurement_unit "$unit"
|
|
||||||
send_success "Measurement unit updated successfully" "{\"unit\":\"$unit\"}"
|
|
||||||
else
|
|
||||||
send_error "INVALID_UNIT" "Invalid unit provided. Must be 'km' or 'mi'."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
send_error "NO_DATA" "No data provided"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle DELETE request - Reset to default (delete configuration)
|
|
||||||
handle_delete() {
|
|
||||||
log_message "DELETE request received"
|
|
||||||
|
|
||||||
if delete_measurement_unit; then
|
|
||||||
# Get the default unit that will be used
|
|
||||||
local default_unit=$(get_default_unit)
|
|
||||||
send_success "Measurement unit reset to default" "{\"unit\":\"$default_unit\",\"isDefault\":true}"
|
|
||||||
else
|
|
||||||
send_error "NOT_FOUND" "Measurement unit configuration not found"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle OPTIONS request for CORS preflight
|
|
||||||
handle_options() {
|
|
||||||
log_message "OPTIONS request received"
|
|
||||||
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 "Measurement units script called with method: ${REQUEST_METHOD:-GET}"
|
|
||||||
|
|
||||||
# Handle different HTTP methods
|
|
||||||
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
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Memory Settings Configuration Script
|
|
||||||
# Manages memory service (enable/disable) and daemon settings with dynamic service management
|
|
||||||
|
|
||||||
# Handle OPTIONS request first
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "Content-Type: text/plain"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo "Access-Control-Max-Age: 86400"
|
|
||||||
echo ""
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 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 paths
|
|
||||||
CONFIG_DIR="/etc/quecmanager/settings"
|
|
||||||
CONFIG_FILE="$CONFIG_DIR/memory_settings.conf"
|
|
||||||
FALLBACK_CONFIG_DIR="/tmp/quecmanager/settings"
|
|
||||||
FALLBACK_CONFIG_FILE="$FALLBACK_CONFIG_DIR/memory_settings.conf"
|
|
||||||
LOG_FILE="/tmp/memory_settings.log"
|
|
||||||
SERVICES_INIT="/etc/init.d/quecmanager_services"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get current configuration
|
|
||||||
get_config() {
|
|
||||||
# Defaults
|
|
||||||
ENABLED="false"
|
|
||||||
INTERVAL="1"
|
|
||||||
|
|
||||||
# Try primary config first, then fallback
|
|
||||||
local config_to_read=""
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
config_to_read="$CONFIG_FILE"
|
|
||||||
elif [ -f "$FALLBACK_CONFIG_FILE" ]; then
|
|
||||||
config_to_read="$FALLBACK_CONFIG_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$config_to_read" ]; then
|
|
||||||
local enabled_val=$(grep "^MEMORY_ENABLED=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2)
|
|
||||||
local interval_val=$(grep "^MEMORY_INTERVAL=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2)
|
|
||||||
|
|
||||||
case "$enabled_val" in
|
|
||||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
|
||||||
*) ENABLED="false" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if echo "$interval_val" | grep -qE '^[0-9]+$' && [ "$interval_val" -ge 1 ] && [ "$interval_val" -le 10 ]; then
|
|
||||||
INTERVAL="$interval_val"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Save configuration
|
|
||||||
save_config() {
|
|
||||||
local enabled="$1"
|
|
||||||
local interval="$2"
|
|
||||||
|
|
||||||
# Try primary location first
|
|
||||||
if mkdir -p "$CONFIG_DIR" 2>/dev/null && [ -w "$CONFIG_DIR" ]; then
|
|
||||||
{
|
|
||||||
echo "MEMORY_ENABLED=$enabled"
|
|
||||||
echo "MEMORY_INTERVAL=$interval"
|
|
||||||
} > "$CONFIG_FILE" && chmod 644 "$CONFIG_FILE" 2>/dev/null
|
|
||||||
log_message "Saved config to primary location: enabled=$enabled, interval=$interval"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback to tmp
|
|
||||||
mkdir -p "$FALLBACK_CONFIG_DIR" 2>/dev/null
|
|
||||||
{
|
|
||||||
echo "MEMORY_ENABLED=$enabled"
|
|
||||||
echo "MEMORY_INTERVAL=$interval"
|
|
||||||
} > "$FALLBACK_CONFIG_FILE" && chmod 644 "$FALLBACK_CONFIG_FILE" 2>/dev/null
|
|
||||||
log_message "Saved config to fallback location: enabled=$enabled, interval=$interval"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add memory daemon to services init script
|
|
||||||
add_memory_daemon_to_services() {
|
|
||||||
if [ ! -f "$SERVICES_INIT" ]; then
|
|
||||||
log_message "Services init file not found: $SERVICES_INIT"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if memory daemon is already present
|
|
||||||
if grep -q "memory_daemon.sh" "$SERVICES_INIT" 2>/dev/null; then
|
|
||||||
log_message "Memory daemon already present in services"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a temporary file with the memory daemon block
|
|
||||||
local temp_file="/tmp/services_temp_$$"
|
|
||||||
|
|
||||||
# Find the line before "echo \"All QuecManager services Started\"" and insert memory daemon
|
|
||||||
awk '
|
|
||||||
/echo "All QuecManager services Started"/ {
|
|
||||||
print " # Start memory daemon"
|
|
||||||
print " echo \"Starting Memory Daemon...\""
|
|
||||||
print " procd_open_instance"
|
|
||||||
print " procd_set_param command /www/cgi-bin/services/memory_daemon.sh"
|
|
||||||
print " procd_set_param respawn"
|
|
||||||
print " procd_set_param stdout 1"
|
|
||||||
print " procd_set_param stderr 1"
|
|
||||||
print " procd_close_instance"
|
|
||||||
print " echo \"Memory Daemon started\""
|
|
||||||
print ""
|
|
||||||
}
|
|
||||||
{ print }
|
|
||||||
' "$SERVICES_INIT" > "$temp_file"
|
|
||||||
|
|
||||||
if [ -s "$temp_file" ]; then
|
|
||||||
mv "$temp_file" "$SERVICES_INIT"
|
|
||||||
chmod +x "$SERVICES_INIT"
|
|
||||||
log_message "Added memory daemon to services init script"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
log_message "Failed to add memory daemon to services"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove memory daemon from services init script
|
|
||||||
remove_memory_daemon_from_services() {
|
|
||||||
if [ ! -f "$SERVICES_INIT" ]; then
|
|
||||||
log_message "Services init file not found: $SERVICES_INIT"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if memory daemon is present
|
|
||||||
if ! grep -q "memory_daemon.sh" "$SERVICES_INIT" 2>/dev/null; then
|
|
||||||
log_message "Memory daemon not present in services"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove the memory daemon block (from "# Start memory daemon" to the empty line after)
|
|
||||||
local temp_file="/tmp/services_temp_$$"
|
|
||||||
|
|
||||||
awk '
|
|
||||||
/# Start memory daemon/ { skip=1; next }
|
|
||||||
skip && /^$/ { skip=0; next }
|
|
||||||
!skip { print }
|
|
||||||
' "$SERVICES_INIT" > "$temp_file"
|
|
||||||
|
|
||||||
if [ -s "$temp_file" ]; then
|
|
||||||
mv "$temp_file" "$SERVICES_INIT"
|
|
||||||
chmod +x "$SERVICES_INIT"
|
|
||||||
log_message "Removed memory daemon from services init script"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
log_message "Failed to remove memory daemon from services"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Restart QuecManager services
|
|
||||||
restart_services() {
|
|
||||||
log_message "Restarting QuecManager services..."
|
|
||||||
|
|
||||||
# Stop services
|
|
||||||
if [ -x "$SERVICES_INIT" ]; then
|
|
||||||
"$SERVICES_INIT" stop >/dev/null 2>&1
|
|
||||||
sleep 2
|
|
||||||
"$SERVICES_INIT" start >/dev/null 2>&1
|
|
||||||
log_message "Services restarted successfully"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
log_message "Cannot restart services - init script not found or not executable"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if memory daemon is running
|
|
||||||
is_memory_daemon_running() {
|
|
||||||
pgrep -f "memory_daemon.sh" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle POST request - Update memory setting
|
|
||||||
handle_post() {
|
|
||||||
log_message "POST request received"
|
|
||||||
|
|
||||||
local content_length=${CONTENT_LENGTH:-0}
|
|
||||||
if [ "$content_length" -eq 0 ]; then
|
|
||||||
send_error "NO_DATA" "No data provided"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read POST data
|
|
||||||
local post_data=$(dd bs=$content_length count=1 2>/dev/null)
|
|
||||||
log_message "Received POST data: $post_data"
|
|
||||||
|
|
||||||
# Parse enabled and interval from JSON
|
|
||||||
local enabled=$(echo "$post_data" | sed -n 's/.*"enabled"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p' | tr -d ' "')
|
|
||||||
local interval=$(echo "$post_data" | sed -n 's/.*"interval"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p')
|
|
||||||
|
|
||||||
# Set defaults if not provided
|
|
||||||
[ -z "$enabled" ] && enabled="false"
|
|
||||||
[ -z "$interval" ] && interval="1"
|
|
||||||
|
|
||||||
# Validate input
|
|
||||||
case "$enabled" in
|
|
||||||
true|false) ;;
|
|
||||||
*) send_error "INVALID_SETTING" "Invalid enabled value. Must be true or false." ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if ! echo "$interval" | grep -qE '^[0-9]+$' || [ "$interval" -lt 1 ] || [ "$interval" -gt 10 ]; then
|
|
||||||
send_error "INVALID_INTERVAL" "Interval must be a number between 1 and 10 seconds."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get current config to compare
|
|
||||||
get_config
|
|
||||||
local prev_enabled="$ENABLED"
|
|
||||||
local prev_interval="$INTERVAL"
|
|
||||||
|
|
||||||
# Save new configuration
|
|
||||||
save_config "$enabled" "$interval"
|
|
||||||
|
|
||||||
# Handle service changes
|
|
||||||
if [ "$enabled" = "true" ]; then
|
|
||||||
# Enable memory daemon
|
|
||||||
add_memory_daemon_to_services
|
|
||||||
if [ "$prev_enabled" != "true" ] || [ "$prev_interval" != "$interval" ]; then
|
|
||||||
restart_services
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Disable memory daemon
|
|
||||||
remove_memory_daemon_from_services
|
|
||||||
restart_services
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return current status
|
|
||||||
sleep 1 # Give services time to start/stop
|
|
||||||
local running="false"
|
|
||||||
if is_memory_daemon_running; then
|
|
||||||
running="true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
send_success "Memory setting updated successfully" "{\"enabled\":$enabled,\"interval\":$interval,\"running\":$running}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle DELETE request - Reset to default
|
|
||||||
handle_delete() {
|
|
||||||
log_message "DELETE request received"
|
|
||||||
|
|
||||||
# Remove memory daemon from services and restart
|
|
||||||
remove_memory_daemon_from_services
|
|
||||||
restart_services
|
|
||||||
|
|
||||||
# Remove config files
|
|
||||||
rm -f "$CONFIG_FILE" "$FALLBACK_CONFIG_FILE" 2>/dev/null
|
|
||||||
|
|
||||||
send_success "Memory setting reset to default (disabled)" "{\"enabled\":false,\"interval\":1,\"running\":false,\"isDefault\":true}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
log_message "Memory settings script called with method: ${REQUEST_METHOD:-GET}"
|
|
||||||
|
|
||||||
case "${REQUEST_METHOD:-GET}" in
|
|
||||||
POST)
|
|
||||||
handle_post
|
|
||||||
;;
|
|
||||||
DELETE)
|
|
||||||
handle_delete
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
send_error "METHOD_NOT_ALLOWED" "HTTP method ${REQUEST_METHOD} not supported."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,330 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Ping Settings Configuration Script
|
|
||||||
# Manages ping service (enable/disable) and daemon settings
|
|
||||||
# Author: dr-dolomite
|
|
||||||
# Date: 2025-08-04
|
|
||||||
|
|
||||||
# Handle OPTIONS request first (before any headers)
|
|
||||||
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
|
|
||||||
echo "Content-Type: text/plain"
|
|
||||||
echo "Access-Control-Allow-Origin: *"
|
|
||||||
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type"
|
|
||||||
echo "Access-Control-Max-Age: 86400"
|
|
||||||
echo ""
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set content type and CORS headers for other requests
|
|
||||||
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/ping_settings.conf"
|
|
||||||
FALLBACK_CONFIG_DIR="/tmp/quecmanager/settings"
|
|
||||||
FALLBACK_CONFIG_FILE="$FALLBACK_CONFIG_DIR/ping_settings.conf"
|
|
||||||
LOG_FILE="/tmp/ping_settings.log"
|
|
||||||
PID_FILE="/tmp/quecmanager/ping_daemon.pid"
|
|
||||||
# Prefer the new services location, fall back to the legacy path for compatibility
|
|
||||||
DAEMON_RELATIVE_PATHS="/cgi-bin/services/ping_daemon.sh"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Resolve config file for reading: prefer primary, then fallback
|
|
||||||
resolve_config_for_read() {
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
return 0
|
|
||||||
elif [ -f "$FALLBACK_CONFIG_FILE" ]; then
|
|
||||||
CONFIG_FILE="$FALLBACK_CONFIG_FILE"
|
|
||||||
CONFIG_DIR="$FALLBACK_CONFIG_DIR"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
# Default to primary path if none exist
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Determine daemon path (absolute) based on typical web root layouts
|
|
||||||
resolve_daemon_path() {
|
|
||||||
# Common locations where CGI/WWW is mounted
|
|
||||||
for rel in $DAEMON_RELATIVE_PATHS; do
|
|
||||||
for base in \
|
|
||||||
/www \
|
|
||||||
/; do
|
|
||||||
if [ -x "$base$rel" ]; then
|
|
||||||
echo "$base$rel"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Also try as-is if busybox httpd cwd matches web root
|
|
||||||
if [ -x "$rel" ]; then
|
|
||||||
echo "$rel"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Nothing found; return first candidate as a best-effort path
|
|
||||||
set -- $DAEMON_RELATIVE_PATHS
|
|
||||||
echo "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_running() {
|
|
||||||
if [ -f "$PID_FILE" ]; then
|
|
||||||
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
|
||||||
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
start_daemon() {
|
|
||||||
# Ensure /tmp/quecmanager exists for PID
|
|
||||||
[ -d "/tmp/quecmanager" ] || mkdir -p "/tmp/quecmanager"
|
|
||||||
|
|
||||||
if daemon_running; then
|
|
||||||
log_message "Daemon already running"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
local daemon_path
|
|
||||||
daemon_path="$(resolve_daemon_path)"
|
|
||||||
if [ ! -x "$daemon_path" ]; then
|
|
||||||
# Try to make it executable if present
|
|
||||||
if [ -f "$daemon_path" ]; then
|
|
||||||
chmod +x "$daemon_path" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -x "$daemon_path" ]; then
|
|
||||||
nohup "$daemon_path" >/dev/null 2>&1 &
|
|
||||||
log_message "Started ping daemon: $daemon_path (pid $!)"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
log_message "Daemon script not found or not executable: $daemon_path"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_daemon() {
|
|
||||||
if daemon_running; then
|
|
||||||
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
|
||||||
if [ -n "${pid:-}" ]; then
|
|
||||||
kill "$pid" 2>/dev/null || true
|
|
||||||
sleep 0.2
|
|
||||||
kill -9 "$pid" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
rm -f "$PID_FILE" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get current ping setting
|
|
||||||
get_config_values() {
|
|
||||||
# defaults
|
|
||||||
ENABLED="true"
|
|
||||||
HOST="8.8.8.8"
|
|
||||||
INTERVAL="5"
|
|
||||||
|
|
||||||
resolve_config_for_read
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
val=$(grep -E "^PING_ENABLED=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
|
|
||||||
if [ -n "${val:-}" ]; then
|
|
||||||
case "$val" in
|
|
||||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
|
||||||
*) ENABLED="false" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
val=$(grep -E "^PING_HOST=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
|
|
||||||
[ -n "${val:-}" ] && HOST="$val"
|
|
||||||
val=$(grep -E "^PING_INTERVAL=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
|
|
||||||
if echo "${val:-}" | grep -qE '^[0-9]+$'; then
|
|
||||||
INTERVAL="$val"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Save ping setting to config file
|
|
||||||
save_config() {
|
|
||||||
local enabled="$1"
|
|
||||||
local host="$2"
|
|
||||||
local interval="$3"
|
|
||||||
|
|
||||||
# Try primary directory first
|
|
||||||
if mkdir -p "$CONFIG_DIR" 2>/dev/null; then
|
|
||||||
local tmp="$CONFIG_FILE.tmp.$$"
|
|
||||||
echo "PING_ENABLED=$enabled" > "$tmp" || rm -f "$tmp" || return 1
|
|
||||||
echo "PING_HOST=$host" >> "$tmp" || rm -f "$tmp" || return 1
|
|
||||||
echo "PING_INTERVAL=$interval" >> "$tmp" || rm -f "$tmp" || return 1
|
|
||||||
if mv -f "$tmp" "$CONFIG_FILE" 2>/dev/null; then
|
|
||||||
chmod 644 "$CONFIG_FILE" 2>/dev/null || true
|
|
||||||
log_message "Saved ping config (primary): enabled=$enabled host=$host interval=$interval"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback to /tmp
|
|
||||||
mkdir -p "$FALLBACK_CONFIG_DIR" 2>/dev/null || true
|
|
||||||
local tmp2="$FALLBACK_CONFIG_FILE.tmp.$$"
|
|
||||||
echo "PING_ENABLED=$enabled" > "$tmp2" || rm -f "$tmp2" || return 1
|
|
||||||
echo "PING_HOST=$host" >> "$tmp2" || rm -f "$tmp2" || return 1
|
|
||||||
echo "PING_INTERVAL=$interval" >> "$tmp2" || rm -f "$tmp2" || return 1
|
|
||||||
mv -f "$tmp2" "$FALLBACK_CONFIG_FILE" 2>/dev/null || return 1
|
|
||||||
chmod 644 "$FALLBACK_CONFIG_FILE" 2>/dev/null || true
|
|
||||||
# Point CONFIG_FILE to fallback for subsequent reads in this request
|
|
||||||
CONFIG_FILE="$FALLBACK_CONFIG_FILE"; CONFIG_DIR="$FALLBACK_CONFIG_DIR"
|
|
||||||
log_message "Saved ping config (fallback): enabled=$enabled host=$host interval=$interval"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete ping configuration (reset to default)
|
|
||||||
delete_ping_setting() {
|
|
||||||
local removed=1
|
|
||||||
for f in "$CONFIG_FILE" "$FALLBACK_CONFIG_FILE"; do
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
sed -i '/^PING_ENABLED=/d' "$f" 2>/dev/null || true
|
|
||||||
sed -i '/^PING_HOST=/d' "$f" 2>/dev/null || true
|
|
||||||
sed -i '/^PING_INTERVAL=/d' "$f" 2>/dev/null || true
|
|
||||||
log_message "Deleted ping configuration entries in $f"
|
|
||||||
[ -s "$f" ] || { rm -f "$f" 2>/dev/null || true; log_message "Removed empty config file $f"; }
|
|
||||||
removed=0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return $removed
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle GET request - Retrieve ping setting
|
|
||||||
handle_get() {
|
|
||||||
log_message "GET request received"
|
|
||||||
get_config_values
|
|
||||||
local running=false
|
|
||||||
if daemon_running; then running=true; fi
|
|
||||||
local is_default=true
|
|
||||||
if [ -f "$CONFIG_FILE" ] && grep -q "^PING_ENABLED=" "$CONFIG_FILE"; then
|
|
||||||
is_default=false
|
|
||||||
fi
|
|
||||||
send_success "Ping configuration retrieved" "{\"enabled\":$ENABLED,\"host\":\"$HOST\",\"interval\":$INTERVAL,\"running\":$running,\"isDefault\":$is_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle POST request - Update ping setting
|
|
||||||
handle_post() {
|
|
||||||
log_message "POST request received"
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
log_message "Received POST data: $post_data"
|
|
||||||
|
|
||||||
# Parse fields
|
|
||||||
local enabled host interval
|
|
||||||
enabled=$(echo "$post_data" | sed -n 's/.*"enabled"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p' | tr -d ' ' | sed 's/"//g')
|
|
||||||
host=$(echo "$post_data" | sed -n 's/.*"host"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
||||||
interval=$(echo "$post_data" | sed -n 's/.*"interval"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p')
|
|
||||||
|
|
||||||
# Defaults when missing
|
|
||||||
[ -z "$enabled" ] && enabled="true"
|
|
||||||
[ -z "$host" ] && host="8.8.8.8"
|
|
||||||
[ -z "$interval" ] && interval="5"
|
|
||||||
|
|
||||||
# Validate
|
|
||||||
case "$enabled" in
|
|
||||||
true|false) : ;;
|
|
||||||
*) send_error "INVALID_SETTING" "Invalid enabled value. Must be true or false." ;;
|
|
||||||
esac
|
|
||||||
if ! echo "$interval" | grep -qE '^[0-9]+$'; then
|
|
||||||
send_error "INVALID_INTERVAL" "Interval must be a number (seconds)."
|
|
||||||
fi
|
|
||||||
if [ "$interval" -lt 1 ] || [ "$interval" -gt 3600 ]; then
|
|
||||||
send_error "INVALID_INTERVAL" "Interval must be between 1 and 3600 seconds."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Capture previous values to decide on restart
|
|
||||||
get_config_values
|
|
||||||
local prev_enabled="$ENABLED"
|
|
||||||
local prev_host="$HOST"
|
|
||||||
local prev_interval="$INTERVAL"
|
|
||||||
|
|
||||||
save_config "$enabled" "$host" "$interval" || send_error "WRITE_FAILED" "Failed to save configuration"
|
|
||||||
|
|
||||||
if [ "$enabled" = "true" ]; then
|
|
||||||
if daemon_running; then
|
|
||||||
# Restart only if effective parameters changed
|
|
||||||
if [ "$prev_host" != "$host" ] || [ "$prev_interval" != "$interval" ] || [ "$prev_enabled" != "$enabled" ]; then
|
|
||||||
log_message "Config change detected (host/interval/enabled). Restarting daemon."
|
|
||||||
stop_daemon
|
|
||||||
start_daemon || log_message "Failed to restart daemon"
|
|
||||||
else
|
|
||||||
log_message "No change requiring restart; daemon remains running"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
start_daemon || log_message "Failed to start daemon"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
stop_daemon
|
|
||||||
fi
|
|
||||||
|
|
||||||
get_config_values
|
|
||||||
local running=false
|
|
||||||
if daemon_running; then running=true; fi
|
|
||||||
send_success "Ping setting updated successfully" "{\"enabled\":$ENABLED,\"host\":\"$HOST\",\"interval\":$INTERVAL,\"running\":$running}"
|
|
||||||
else
|
|
||||||
send_error "NO_DATA" "No data provided"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle DELETE request - Reset to default (delete configuration)
|
|
||||||
handle_delete() {
|
|
||||||
log_message "DELETE request received"
|
|
||||||
stop_daemon
|
|
||||||
if delete_ping_setting; then
|
|
||||||
# Default is enabled
|
|
||||||
send_success "Ping setting reset to default" "{\"enabled\":true,\"isDefault\":true,\"running\":false}"
|
|
||||||
else
|
|
||||||
send_error "NOT_FOUND" "Ping setting configuration not found"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
log_message "Ping settings script called with method: ${REQUEST_METHOD:-GET}"
|
|
||||||
|
|
||||||
# Handle different HTTP methods
|
|
||||||
case "${REQUEST_METHOD:-GET}" in
|
|
||||||
GET)
|
|
||||||
handle_get
|
|
||||||
;;
|
|
||||||
POST)
|
|
||||||
handle_post
|
|
||||||
;;
|
|
||||||
DELETE)
|
|
||||||
handle_delete
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
send_error "METHOD_NOT_ALLOWED" "HTTP method ${REQUEST_METHOD} not supported"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Ultra-Simple Profile Picture Management Script
|
|
||||||
# Handles direct file uploads without base64 encoding
|
|
||||||
# Author: dr-dolomite
|
|
||||||
# Date: 2025-08-04
|
|
||||||
|
|
||||||
# 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, Authorization"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
PROFILE_DIR="/www/assets/profile"
|
|
||||||
PROFILE_IMAGE="$PROFILE_DIR/profile.jpg"
|
|
||||||
TEMP_DIR="/tmp"
|
|
||||||
LOG_FILE="/tmp/profile_picture.log"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get file size
|
|
||||||
get_file_size() {
|
|
||||||
local file="$1"
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
stat -c%s "$file" 2>/dev/null || wc -c < "$file"
|
|
||||||
else
|
|
||||||
echo 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create profile directory if it doesn't exist
|
|
||||||
ensure_profile_directory() {
|
|
||||||
if [ ! -d "$PROFILE_DIR" ]; then
|
|
||||||
mkdir -p "$PROFILE_DIR"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
send_error "DIRECTORY_ERROR" "Failed to create profile directory"
|
|
||||||
fi
|
|
||||||
chmod 755 "$PROFILE_DIR"
|
|
||||||
log_message "Created profile directory: $PROFILE_DIR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle GET request - Fetch profile picture
|
|
||||||
handle_get() {
|
|
||||||
log_message "GET request received"
|
|
||||||
|
|
||||||
if [ -f "$PROFILE_IMAGE" ]; then
|
|
||||||
# Get file information
|
|
||||||
local file_size=$(get_file_size "$PROFILE_IMAGE")
|
|
||||||
local file_modified=$(stat -c %Y "$PROFILE_IMAGE" 2>/dev/null || echo "0")
|
|
||||||
|
|
||||||
# Return file information and base64 encoded image
|
|
||||||
local base64_image=""
|
|
||||||
if command -v base64 >/dev/null 2>&1; then
|
|
||||||
base64_image=$(base64 -w 0 "$PROFILE_IMAGE" 2>/dev/null)
|
|
||||||
elif command -v openssl >/dev/null 2>&1; then
|
|
||||||
base64_image=$(openssl base64 -in "$PROFILE_IMAGE" | tr -d '\n' 2>/dev/null)
|
|
||||||
elif command -v python3 >/dev/null 2>&1; then
|
|
||||||
base64_image=$(python3 -c "
|
|
||||||
import base64
|
|
||||||
try:
|
|
||||||
with open('$PROFILE_IMAGE', 'rb') as f:
|
|
||||||
data = f.read()
|
|
||||||
encoded = base64.b64encode(data).decode('ascii')
|
|
||||||
print(encoded)
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
" 2>/dev/null)
|
|
||||||
elif command -v busybox >/dev/null 2>&1; then
|
|
||||||
base64_image=$(busybox base64 "$PROFILE_IMAGE" | tr -d '\n' 2>/dev/null)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$base64_image" ]; then
|
|
||||||
local file_type=$(file -b --mime-type "$PROFILE_IMAGE" 2>/dev/null || echo "image/jpeg")
|
|
||||||
send_success "Profile picture found" "{\"exists\":true,\"size\":$file_size,\"modified\":$file_modified,\"type\":\"$file_type\",\"data\":\"data:$file_type;base64,$base64_image\"}"
|
|
||||||
else
|
|
||||||
send_success "Profile picture found but could not encode" "{\"exists\":true,\"size\":$file_size,\"modified\":$file_modified,\"data\":null}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_message "No profile picture found"
|
|
||||||
echo "{\"status\":\"error\",\"code\":\"NO_IMAGE_FOUND\",\"message\":\"No profile picture found\"}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle POST request - Direct file upload (no base64)
|
|
||||||
handle_post() {
|
|
||||||
log_message "POST request received"
|
|
||||||
ensure_profile_directory
|
|
||||||
|
|
||||||
# Create temporary file with unique name
|
|
||||||
local temp_file="$TEMP_DIR/profile_upload_$$"
|
|
||||||
|
|
||||||
log_message "Content-Type: ${CONTENT_TYPE:-unknown}"
|
|
||||||
log_message "Content-Length: ${CONTENT_LENGTH:-unknown}"
|
|
||||||
|
|
||||||
# Read the raw uploaded file data directly to temp file
|
|
||||||
cat > "$temp_file"
|
|
||||||
|
|
||||||
# Check if file was created and has content
|
|
||||||
if [ ! -f "$temp_file" ]; then
|
|
||||||
send_error "UPLOAD_ERROR" "Failed to receive uploaded file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local temp_size=$(get_file_size "$temp_file")
|
|
||||||
log_message "Received file size: $temp_size bytes"
|
|
||||||
|
|
||||||
if [ "$temp_size" -eq 0 ]; then
|
|
||||||
rm -f "$temp_file"
|
|
||||||
send_error "UPLOAD_ERROR" "Received empty file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Simply move the uploaded file to profile location (rename operation)
|
|
||||||
if mv "$temp_file" "$PROFILE_IMAGE"; then
|
|
||||||
chmod 644 "$PROFILE_IMAGE"
|
|
||||||
local file_size=$(get_file_size "$PROFILE_IMAGE")
|
|
||||||
log_message "Profile picture saved successfully, size: $file_size bytes"
|
|
||||||
send_success "Profile picture uploaded successfully" "{\"size\":$file_size,\"path\":\"$PROFILE_IMAGE\"}"
|
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
send_error "SAVE_ERROR" "Failed to save profile picture"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle DELETE request - Remove profile picture
|
|
||||||
handle_delete() {
|
|
||||||
log_message "DELETE request received"
|
|
||||||
|
|
||||||
if [ -f "$PROFILE_IMAGE" ]; then
|
|
||||||
if rm "$PROFILE_IMAGE"; then
|
|
||||||
send_success "Profile picture deleted successfully"
|
|
||||||
else
|
|
||||||
send_error "DELETE_ERROR" "Failed to delete profile picture"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
send_error "NO_IMAGE_FOUND" "No profile picture found to delete"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle OPTIONS request for CORS preflight
|
|
||||||
handle_options() {
|
|
||||||
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
|
|
||||||
echo "Access-Control-Allow-Headers: Content-Type, Authorization"
|
|
||||||
echo "Access-Control-Max-Age: 86400"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
log_message "Profile picture script called with method: ${REQUEST_METHOD:-GET}"
|
|
||||||
|
|
||||||
# Handle different HTTP methods
|
|
||||||
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
|
|
||||||
@@ -2,9 +2,6 @@
|
|||||||
# AT Queue Manager for OpenWRT with Preemption Support and Token System
|
# AT Queue Manager for OpenWRT with Preemption Support and Token System
|
||||||
# Located in /www/cgi-bin/services/at_queue_manager
|
# Located in /www/cgi-bin/services/at_queue_manager
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
QUEUE_DIR="/tmp/at_queue"
|
QUEUE_DIR="/tmp/at_queue"
|
||||||
QUEUE_FILE="$QUEUE_DIR/queue"
|
QUEUE_FILE="$QUEUE_DIR/queue"
|
||||||
@@ -18,32 +15,6 @@ RESULTS_MAX_AGE=3600 # 1 hour in seconds
|
|||||||
POLL_INTERVAL=0.01
|
POLL_INTERVAL=0.01
|
||||||
PREEMPTION_THRESHOLD=2 # 3 seconds threshold for preemption
|
PREEMPTION_THRESHOLD=2 # 3 seconds threshold for preemption
|
||||||
TOKEN_TIMEOUT=30 # seconds before token expires
|
TOKEN_TIMEOUT=30 # seconds before token expires
|
||||||
SCRIPT_NAME_LOG="at_queue_manager"
|
|
||||||
|
|
||||||
# Logging function - uses both centralized and system logging
|
|
||||||
log_at_queue() {
|
|
||||||
local level="$1"
|
|
||||||
local message="$2"
|
|
||||||
|
|
||||||
# Use centralized logging
|
|
||||||
case "$level" in
|
|
||||||
"error")
|
|
||||||
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"warn")
|
|
||||||
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"debug")
|
|
||||||
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Also maintain system logging for compatibility
|
|
||||||
logger -t at_queue -p "daemon.$level" "$message"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Utility function for JSON escaping
|
# Utility function for JSON escaping
|
||||||
escape_json() {
|
escape_json() {
|
||||||
@@ -68,7 +39,7 @@ acquire_lock() {
|
|||||||
|
|
||||||
while [ $attempt -lt $timeout ]; do
|
while [ $attempt -lt $timeout ]; do
|
||||||
if mkdir "$LOCK_DIR" 2>/dev/null; then
|
if mkdir "$LOCK_DIR" 2>/dev/null; then
|
||||||
log_at_queue "debug" "Lock acquired"
|
logger -t at_queue -p daemon.debug "Lock acquired"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -76,18 +47,18 @@ acquire_lock() {
|
|||||||
attempt=$((attempt + 1))
|
attempt=$((attempt + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
log_at_queue "error" "Failed to acquire lock after $timeout attempts"
|
logger -t at_queue -p daemon.error "Failed to acquire lock after $timeout attempts"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
release_lock() {
|
release_lock() {
|
||||||
if [ -d "$LOCK_DIR" ]; then
|
if [ -d "$LOCK_DIR" ]; then
|
||||||
rmdir "$LOCK_DIR" 2>/dev/null
|
rmdir "$LOCK_DIR" 2>/dev/null
|
||||||
log_at_queue "debug" "Lock released"
|
logger -t at_queue -p daemon.debug "Lock released"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_at_queue "error" "Lock directory doesn't exist"
|
logger -t at_queue -p daemon.error "Lock directory doesn't exist"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +69,7 @@ init_queue_system() {
|
|||||||
chmod 755 "$QUEUE_DIR"
|
chmod 755 "$QUEUE_DIR"
|
||||||
chmod 644 "$QUEUE_FILE"
|
chmod 644 "$QUEUE_FILE"
|
||||||
chmod 755 "$RESULTS_DIR"
|
chmod 755 "$RESULTS_DIR"
|
||||||
log_at_queue "info" "Queue system initialized"
|
logger -t at_queue -p daemon.info "Queue system initialized"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Cleanup old results and tracking files
|
# Cleanup old results and tracking files
|
||||||
@@ -109,7 +80,7 @@ cleanup_old_results() {
|
|||||||
find "$QUEUE_DIR" -name "pid.*" -type f -mmin +60 -delete 2>/dev/null
|
find "$QUEUE_DIR" -name "pid.*" -type f -mmin +60 -delete 2>/dev/null
|
||||||
find "$QUEUE_DIR" -name "*.exit" -type f -mmin +60 -delete 2>/dev/null
|
find "$QUEUE_DIR" -name "*.exit" -type f -mmin +60 -delete 2>/dev/null
|
||||||
find "$QUEUE_DIR" -name "start_time.*" -type f -mmin +60 -delete 2>/dev/null
|
find "$QUEUE_DIR" -name "start_time.*" -type f -mmin +60 -delete 2>/dev/null
|
||||||
log_at_queue "debug" "Cleaned up old tracking files"
|
logger -t at_queue -p daemon.debug "Cleaned up old tracking files"
|
||||||
|
|
||||||
# Use find with -delete and basic timestamp check for OpenWRT
|
# Use find with -delete and basic timestamp check for OpenWRT
|
||||||
find "$RESULTS_DIR" -name "*.json" -type f -mmin +60 -delete 2>/dev/null || {
|
find "$RESULTS_DIR" -name "*.json" -type f -mmin +60 -delete 2>/dev/null || {
|
||||||
@@ -128,12 +99,12 @@ cleanup_old_results() {
|
|||||||
local token_time=$(cat "$TOKEN_FILE" | jsonfilter -e '@.timestamp')
|
local token_time=$(cat "$TOKEN_FILE" | jsonfilter -e '@.timestamp')
|
||||||
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
|
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
|
||||||
local token_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id')
|
local token_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id')
|
||||||
log_at_queue "warn" "Removing expired token from $token_holder"
|
logger -t at_queue -p daemon.warn "Removing expired token from $token_holder"
|
||||||
rm -f "$TOKEN_FILE"
|
rm -f "$TOKEN_FILE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_at_queue "info" "Cleanup: Removed files older than 1 hour"
|
logger -t at_queue -p daemon.info "Cleanup: Removed files older than 1 hour"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate unique command ID
|
# Generate unique command ID
|
||||||
@@ -151,7 +122,7 @@ start_execution_tracking() {
|
|||||||
echo "$pid" > "$QUEUE_DIR/pid.$cmd_id"
|
echo "$pid" > "$QUEUE_DIR/pid.$cmd_id"
|
||||||
chmod 644 "$QUEUE_DIR/start_time.$cmd_id"
|
chmod 644 "$QUEUE_DIR/start_time.$cmd_id"
|
||||||
chmod 644 "$QUEUE_DIR/pid.$cmd_id"
|
chmod 644 "$QUEUE_DIR/pid.$cmd_id"
|
||||||
log_at_queue "debug" "Started tracking command $cmd_id (PID: $pid)"
|
logger -t at_queue -p daemon.debug "Started tracking command $cmd_id (PID: $pid)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if running command should be preempted
|
# Check if running command should be preempted
|
||||||
@@ -160,7 +131,7 @@ should_preempt() {
|
|||||||
local new_priority="$2"
|
local new_priority="$2"
|
||||||
|
|
||||||
if [ ! -f "$QUEUE_DIR/start_time.$current_cmd_id" ]; then
|
if [ ! -f "$QUEUE_DIR/start_time.$current_cmd_id" ]; then
|
||||||
log_at_queue "debug" "No start time found for $current_cmd_id"
|
logger -t at_queue -p daemon.debug "No start time found for $current_cmd_id"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -173,16 +144,16 @@ should_preempt() {
|
|||||||
if [ -f "$ACTIVE_FILE" ]; then
|
if [ -f "$ACTIVE_FILE" ]; then
|
||||||
current_priority=$(cat "$ACTIVE_FILE" | jsonfilter -e '@.priority')
|
current_priority=$(cat "$ACTIVE_FILE" | jsonfilter -e '@.priority')
|
||||||
else
|
else
|
||||||
log_at_queue "debug" "No active command found"
|
logger -t at_queue -p daemon.debug "No active command found"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $execution_time -gt $PREEMPTION_THRESHOLD ] && [ $new_priority -lt $current_priority ]; then
|
if [ $execution_time -gt $PREEMPTION_THRESHOLD ] && [ $new_priority -lt $current_priority ]; then
|
||||||
log_at_queue "info" "Command $current_cmd_id (priority $current_priority) running for ${execution_time}s is eligible for preemption by priority $new_priority"
|
logger -t at_queue -p daemon.info "Command $current_cmd_id (priority $current_priority) running for ${execution_time}s is eligible for preemption by priority $new_priority"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_at_queue "debug" "Command $current_cmd_id not eligible for preemption (time: ${execution_time}s, current priority: $current_priority, new priority: $new_priority)"
|
logger -t at_queue -p daemon.debug "Command $current_cmd_id not eligible for preemption (time: ${execution_time}s, current priority: $current_priority, new priority: $new_priority)"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +164,7 @@ preempt_command() {
|
|||||||
|
|
||||||
if [ -f "$pid_file" ]; then
|
if [ -f "$pid_file" ]; then
|
||||||
local pid=$(cat "$pid_file")
|
local pid=$(cat "$pid_file")
|
||||||
log_at_queue "info" "Preempting command $cmd_id (PID: $pid)"
|
logger -t at_queue -p daemon.info "Preempting command $cmd_id (PID: $pid)"
|
||||||
|
|
||||||
# Send SIGTERM first
|
# Send SIGTERM first
|
||||||
kill -TERM $pid 2>/dev/null
|
kill -TERM $pid 2>/dev/null
|
||||||
@@ -204,7 +175,7 @@ preempt_command() {
|
|||||||
# Force kill if still running
|
# Force kill if still running
|
||||||
if kill -0 $pid 2>/dev/null; then
|
if kill -0 $pid 2>/dev/null; then
|
||||||
kill -KILL $pid 2>/dev/null
|
kill -KILL $pid 2>/dev/null
|
||||||
log_at_queue "warn" "Forced termination of command $cmd_id"
|
logger -t at_queue -p daemon.warn "Forced termination of command $cmd_id"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Record preemption result
|
# Record preemption result
|
||||||
@@ -214,11 +185,11 @@ preempt_command() {
|
|||||||
rm -f "$pid_file" "$QUEUE_DIR/start_time.$cmd_id" "$QUEUE_DIR/$cmd_id.exit"
|
rm -f "$pid_file" "$QUEUE_DIR/start_time.$cmd_id" "$QUEUE_DIR/$cmd_id.exit"
|
||||||
[ -f "$ACTIVE_FILE" ] && rm -f "$ACTIVE_FILE"
|
[ -f "$ACTIVE_FILE" ] && rm -f "$ACTIVE_FILE"
|
||||||
|
|
||||||
log_at_queue "info" "Command $cmd_id preemption complete"
|
logger -t at_queue -p daemon.info "Command $cmd_id preemption complete"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_at_queue "warn" "No PID file found for command $cmd_id"
|
logger -t at_queue -p daemon.warn "No PID file found for command $cmd_id"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +227,7 @@ EOF
|
|||||||
|
|
||||||
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
|
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
|
||||||
chmod 644 "$RESULTS_DIR/$cmd_id.json"
|
chmod 644 "$RESULTS_DIR/$cmd_id.json"
|
||||||
log_at_queue "info" "Recorded preemption result for command $cmd_id (duration: ${duration}ms)"
|
logger -t at_queue -p daemon.info "Recorded preemption result for command $cmd_id (duration: ${duration}ms)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Request a token for direct sms_tool execution
|
# Request a token for direct sms_tool execution
|
||||||
@@ -267,7 +238,7 @@ request_token() {
|
|||||||
|
|
||||||
# Acquire lock first
|
# Acquire lock first
|
||||||
if ! acquire_lock; then
|
if ! acquire_lock; then
|
||||||
log_at_queue "error" "Failed to acquire lock for token request"
|
logger -t at_queue -p daemon.error "Failed to acquire lock for token request"
|
||||||
echo "{\"error\":\"Could not acquire lock\",\"status\":\"denied\"}"
|
echo "{\"error\":\"Could not acquire lock\",\"status\":\"denied\"}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -281,11 +252,11 @@ request_token() {
|
|||||||
|
|
||||||
# Check for expired token (> TOKEN_TIMEOUT seconds old)
|
# Check for expired token (> TOKEN_TIMEOUT seconds old)
|
||||||
if [ $((current_time - timestamp)) -gt $TOKEN_TIMEOUT ]; then
|
if [ $((current_time - timestamp)) -gt $TOKEN_TIMEOUT ]; then
|
||||||
log_at_queue "warn" "Found expired token from $current_holder, releasing"
|
logger -t at_queue -p daemon.warn "Found expired token from $current_holder, releasing"
|
||||||
rm -f "$TOKEN_FILE"
|
rm -f "$TOKEN_FILE"
|
||||||
# Check for priority preemption
|
# Check for priority preemption
|
||||||
elif [ $priority -lt $current_priority ]; then
|
elif [ $priority -lt $current_priority ]; then
|
||||||
log_at_queue "info" "Preempting token from $current_holder (priority: $current_priority) for $requestor_id (priority: $priority)"
|
logger -t at_queue -p daemon.info "Preempting token from $current_holder (priority: $current_priority) for $requestor_id (priority: $priority)"
|
||||||
rm -f "$TOKEN_FILE"
|
rm -f "$TOKEN_FILE"
|
||||||
else
|
else
|
||||||
# Token in use and cannot be preempted
|
# Token in use and cannot be preempted
|
||||||
@@ -307,7 +278,7 @@ request_token() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_at_queue "info" "Direct execution with higher priority than active queue command"
|
logger -t at_queue -p daemon.info "Direct execution with higher priority than active queue command"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Grant token
|
# Grant token
|
||||||
@@ -325,7 +296,7 @@ release_token() {
|
|||||||
local requestor_id="$1"
|
local requestor_id="$1"
|
||||||
|
|
||||||
if ! acquire_lock; then
|
if ! acquire_lock; then
|
||||||
log_at_queue "error" "Failed to acquire lock for token release"
|
logger -t at_queue -p daemon.error "Failed to acquire lock for token release"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -334,15 +305,15 @@ release_token() {
|
|||||||
|
|
||||||
if [ "$current_holder" = "$requestor_id" ]; then
|
if [ "$current_holder" = "$requestor_id" ]; then
|
||||||
rm -f "$TOKEN_FILE"
|
rm -f "$TOKEN_FILE"
|
||||||
log_at_queue "debug" "Token released by $requestor_id"
|
logger -t at_queue -p daemon.debug "Token released by $requestor_id"
|
||||||
release_lock
|
release_lock
|
||||||
echo "{\"status\":\"released\"}"
|
echo "{\"status\":\"released\"}"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
log_at_queue "warn" "Token release attempted by $requestor_id but held by $current_holder"
|
logger -t at_queue -p daemon.warn "Token release attempted by $requestor_id but held by $current_holder"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log_at_queue "warn" "Token release attempted but no token exists"
|
logger -t at_queue -p daemon.warn "Token release attempted but no token exists"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
release_lock
|
release_lock
|
||||||
@@ -360,11 +331,11 @@ enqueue_command() {
|
|||||||
# Ensure queue directory exists
|
# Ensure queue directory exists
|
||||||
[ ! -d "$QUEUE_DIR" ] && init_queue_system
|
[ ! -d "$QUEUE_DIR" ] && init_queue_system
|
||||||
|
|
||||||
log_at_queue "info" "Enqueuing command: $cmd (priority: $priority, id: $cmd_id)"
|
logger -t at_queue -p daemon.info "Enqueuing command: $cmd (priority: $priority, id: $cmd_id)"
|
||||||
|
|
||||||
# Acquire lock for queue modification
|
# Acquire lock for queue modification
|
||||||
if ! acquire_lock; then
|
if ! acquire_lock; then
|
||||||
log_at_queue "error" "Failed to acquire lock for enqueuing command"
|
logger -t at_queue -p daemon.error "Failed to acquire lock for enqueuing command"
|
||||||
echo "{\"error\":\"Queue lock acquisition failed\",\"command\":\"$cmd\"}"
|
echo "{\"error\":\"Queue lock acquisition failed\",\"command\":\"$cmd\"}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -387,11 +358,11 @@ enqueue_command() {
|
|||||||
cat "$QUEUE_FILE" >> "$temp_file"
|
cat "$QUEUE_FILE" >> "$temp_file"
|
||||||
mv "$temp_file" "$QUEUE_FILE"
|
mv "$temp_file" "$QUEUE_FILE"
|
||||||
chmod 644 "$QUEUE_FILE"
|
chmod 644 "$QUEUE_FILE"
|
||||||
log_at_queue "info" "Added high priority command to front of queue"
|
logger -t at_queue -p daemon.info "Added high priority command to front of queue"
|
||||||
else
|
else
|
||||||
# Normal priority - append to queue
|
# Normal priority - append to queue
|
||||||
echo "$entry" >> "$QUEUE_FILE"
|
echo "$entry" >> "$QUEUE_FILE"
|
||||||
log_at_queue "info" "Added normal priority command to end of queue"
|
logger -t at_queue -p daemon.info "Added normal priority command to end of queue"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Release lock
|
# Release lock
|
||||||
@@ -408,7 +379,7 @@ dequeue_command() {
|
|||||||
|
|
||||||
# Acquire lock
|
# Acquire lock
|
||||||
if ! acquire_lock; then
|
if ! acquire_lock; then
|
||||||
log_at_queue "error" "Failed to acquire lock for dequeuing command"
|
logger -t at_queue -p daemon.error "Failed to acquire lock for dequeuing command"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -424,7 +395,7 @@ dequeue_command() {
|
|||||||
# Release lock
|
# Release lock
|
||||||
release_lock
|
release_lock
|
||||||
|
|
||||||
log_at_queue "debug" "Dequeued command: $(echo "$cmd_entry" | jsonfilter -e '@.command')"
|
logger -t at_queue -p daemon.debug "Dequeued command: $(echo "$cmd_entry" | jsonfilter -e '@.command')"
|
||||||
echo "$cmd_entry"
|
echo "$cmd_entry"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +433,7 @@ execute_with_timeout() {
|
|||||||
# Start execution tracking
|
# Start execution tracking
|
||||||
start_execution_tracking "$cmd_id" "$pid"
|
start_execution_tracking "$cmd_id" "$pid"
|
||||||
|
|
||||||
log_at_queue "debug" "Started command execution: $command (PID: $pid)"
|
logger -t at_queue -p daemon.debug "Started command execution: $command (PID: $pid)"
|
||||||
|
|
||||||
# Wait for completion with shorter polling interval
|
# Wait for completion with shorter polling interval
|
||||||
local start_time=$(date +%s)
|
local start_time=$(date +%s)
|
||||||
@@ -476,7 +447,7 @@ execute_with_timeout() {
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
|
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
|
||||||
|
|
||||||
log_at_queue "debug" "Command completed with exit code $exit_code"
|
logger -t at_queue -p daemon.debug "Command completed with exit code $exit_code"
|
||||||
echo "$output"
|
echo "$output"
|
||||||
return $exit_code
|
return $exit_code
|
||||||
fi
|
fi
|
||||||
@@ -500,7 +471,7 @@ execute_with_timeout() {
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
|
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
|
||||||
|
|
||||||
log_at_queue "warn" "Command timed out after $timeout seconds"
|
logger -t at_queue -p daemon.warn "Command timed out after $timeout seconds"
|
||||||
echo "${partial_output:-Command timed out after $timeout seconds}"
|
echo "${partial_output:-Command timed out after $timeout seconds}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -516,7 +487,7 @@ execute_command() {
|
|||||||
|
|
||||||
local start_time=$(date +%s%3N)
|
local start_time=$(date +%s%3N)
|
||||||
|
|
||||||
log_at_queue "info" "Executing command $cmd_id: $cmd_text (priority: $priority)"
|
logger -t at_queue -p daemon.info "Executing command $cmd_id: $cmd_text (priority: $priority)"
|
||||||
|
|
||||||
# Execute command with timeout
|
# Execute command with timeout
|
||||||
local result=$(execute_with_timeout "$cmd_text" $MAX_TIMEOUT "$cmd_id")
|
local result=$(execute_with_timeout "$cmd_text" $MAX_TIMEOUT "$cmd_id")
|
||||||
@@ -530,16 +501,16 @@ execute_command() {
|
|||||||
|
|
||||||
if [ $exit_code -eq 124 ]; then
|
if [ $exit_code -eq 124 ]; then
|
||||||
status="timeout"
|
status="timeout"
|
||||||
log_at_queue "error" "Command $cmd_id timed out after ${duration}ms"
|
logger -t at_queue -p daemon.error "Command $cmd_id timed out after ${duration}ms"
|
||||||
elif echo "$result" | grep -q "OK"; then
|
elif echo "$result" | grep -q "OK"; then
|
||||||
status="success"
|
status="success"
|
||||||
log_level="info"
|
log_level="info"
|
||||||
log_at_queue "info" "Command $cmd_id completed successfully in ${duration}ms"
|
logger -t at_queue -p daemon.info "Command $cmd_id completed successfully in ${duration}ms"
|
||||||
elif echo "$result" | grep -q "CME ERROR"; then
|
elif echo "$result" | grep -q "CME ERROR"; then
|
||||||
status="cme_error"
|
status="cme_error"
|
||||||
log_at_queue "error" "Command $cmd_id failed with CME ERROR in ${duration}ms"
|
logger -t at_queue -p daemon.error "Command $cmd_id failed with CME ERROR in ${duration}ms"
|
||||||
else
|
else
|
||||||
log_at_queue "error" "Command $cmd_id failed with general error in ${duration}ms"
|
logger -t at_queue -p daemon.error "Command $cmd_id failed with general error in ${duration}ms"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean and escape the output
|
# Clean and escape the output
|
||||||
@@ -565,7 +536,7 @@ EOF
|
|||||||
|
|
||||||
# Acquire lock for writing result
|
# Acquire lock for writing result
|
||||||
if ! acquire_lock; then
|
if ! acquire_lock; then
|
||||||
log_at_queue "error" "Failed to acquire lock for writing result"
|
logger -t at_queue -p daemon.error "Failed to acquire lock for writing result"
|
||||||
else
|
else
|
||||||
# Save response
|
# Save response
|
||||||
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
|
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
|
||||||
@@ -590,7 +561,7 @@ process_queue() {
|
|||||||
# Make sure the lock directory doesn't exist at startup
|
# Make sure the lock directory doesn't exist at startup
|
||||||
[ -d "$LOCK_DIR" ] && rmdir "$LOCK_DIR" 2>/dev/null
|
[ -d "$LOCK_DIR" ] && rmdir "$LOCK_DIR" 2>/dev/null
|
||||||
|
|
||||||
log_at_queue "info" "Started queue processing daemon"
|
logger -t at_queue -p daemon.info "Started queue processing daemon"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Quick cleanup check
|
# Quick cleanup check
|
||||||
@@ -608,12 +579,12 @@ process_queue() {
|
|||||||
|
|
||||||
# Check for expired token
|
# Check for expired token
|
||||||
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
|
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
|
||||||
log_at_queue "warn" "Removing expired token from $token_holder"
|
logger -t at_queue -p daemon.warn "Removing expired token from $token_holder"
|
||||||
rm -f "$TOKEN_FILE"
|
rm -f "$TOKEN_FILE"
|
||||||
else
|
else
|
||||||
# Log pause status only every 5 seconds to reduce log spam
|
# Log pause status only every 5 seconds to reduce log spam
|
||||||
if [ $((current_time - last_log)) -ge 5 ]; then
|
if [ $((current_time - last_log)) -ge 5 ]; then
|
||||||
log_at_queue "debug" "Queue processing paused, token held by $token_holder"
|
logger -t at_queue -p daemon.debug "Queue processing paused, token held by $token_holder"
|
||||||
last_log=$current_time
|
last_log=$current_time
|
||||||
fi
|
fi
|
||||||
sleep $POLL_INTERVAL
|
sleep $POLL_INTERVAL
|
||||||
@@ -647,42 +618,42 @@ if [ "${SCRIPT_NAME}" != "" ]; then
|
|||||||
case "$action" in
|
case "$action" in
|
||||||
"enqueue")
|
"enqueue")
|
||||||
if [ -n "$command" ]; then
|
if [ -n "$command" ]; then
|
||||||
log_at_queue "info" "CGI: Received enqueue request for command: $command"
|
logger -t at_queue -p daemon.info "CGI: Received enqueue request for command: $command"
|
||||||
enqueue_command "$command" "$priority"
|
enqueue_command "$command" "$priority"
|
||||||
else
|
else
|
||||||
log_at_queue "error" "CGI: Empty command received"
|
logger -t at_queue -p daemon.error "CGI: Empty command received"
|
||||||
echo "{\"error\":\"No command specified\"}"
|
echo "{\"error\":\"No command specified\"}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"status")
|
"status")
|
||||||
if [ -f "$ACTIVE_FILE" ]; then
|
if [ -f "$ACTIVE_FILE" ]; then
|
||||||
log_at_queue "debug" "CGI: Status request - queue active"
|
logger -t at_queue -p daemon.debug "CGI: Status request - queue active"
|
||||||
cat "$ACTIVE_FILE"
|
cat "$ACTIVE_FILE"
|
||||||
else
|
else
|
||||||
log_at_queue "debug" "CGI: Status request - queue idle"
|
logger -t at_queue -p daemon.debug "CGI: Status request - queue idle"
|
||||||
echo "{\"status\":\"idle\"}"
|
echo "{\"status\":\"idle\"}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"request_token")
|
"request_token")
|
||||||
if [ -n "$id" ]; then
|
if [ -n "$id" ]; then
|
||||||
log_at_queue "info" "Token request from $id (priority: ${priority:-10})"
|
logger -t at_queue -p daemon.info "Token request from $id (priority: ${priority:-10})"
|
||||||
request_token "$id" "${priority:-10}" "${timeout:-10}"
|
request_token "$id" "${priority:-10}" "${timeout:-10}"
|
||||||
else
|
else
|
||||||
log_at_queue "error" "Token request missing ID"
|
logger -t at_queue -p daemon.error "Token request missing ID"
|
||||||
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
|
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"release_token")
|
"release_token")
|
||||||
if [ -n "$id" ]; then
|
if [ -n "$id" ]; then
|
||||||
log_at_queue "info" "Token release from $id"
|
logger -t at_queue -p daemon.info "Token release from $id"
|
||||||
release_token "$id"
|
release_token "$id"
|
||||||
else
|
else
|
||||||
log_at_queue "error" "Token release missing ID"
|
logger -t at_queue -p daemon.error "Token release missing ID"
|
||||||
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
|
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
log_at_queue "error" "CGI: Invalid action received: $action"
|
logger -t at_queue -p daemon.error "CGI: Invalid action received: $action"
|
||||||
echo "{\"error\":\"Invalid action\"}"
|
echo "{\"error\":\"Invalid action\"}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# QuecManager Log Cleanup Script
|
|
||||||
# Periodically clean up old log files to prevent /tmp from filling up
|
|
||||||
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
MAX_LOG_AGE_DAYS=7 # Delete logs older than 7 days
|
|
||||||
MAX_BACKUP_FILES=2 # Keep maximum 2 backup files (.1, .2)
|
|
||||||
CLEANUP_LOG_SIZE=1000 # Run cleanup if any log exceeds 1MB
|
|
||||||
|
|
||||||
# Function to log cleanup activities
|
|
||||||
log_cleanup() {
|
|
||||||
qm_log_info "system" "log_cleanup" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Initialize
|
|
||||||
qm_init_logs
|
|
||||||
log_cleanup "Starting log cleanup process"
|
|
||||||
|
|
||||||
# Cleanup function
|
|
||||||
perform_cleanup() {
|
|
||||||
local files_cleaned=0
|
|
||||||
local space_freed=0
|
|
||||||
|
|
||||||
# Clean up old backup files
|
|
||||||
if [ -d "$QM_LOG_BASE" ]; then
|
|
||||||
# Remove backup files older than specified days
|
|
||||||
old_backups=$(find "$QM_LOG_BASE" -name "*.1" -o -name "*.2" -type f -mtime +$MAX_LOG_AGE_DAYS 2>/dev/null)
|
|
||||||
for backup_file in $old_backups; do
|
|
||||||
if [ -f "$backup_file" ]; then
|
|
||||||
file_size=$(du -k "$backup_file" 2>/dev/null | cut -f1)
|
|
||||||
rm -f "$backup_file" 2>/dev/null
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
files_cleaned=$((files_cleaned + 1))
|
|
||||||
space_freed=$((space_freed + ${file_size:-0}))
|
|
||||||
log_cleanup "Removed old backup file: $(basename "$backup_file")"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Force rotation for large log files
|
|
||||||
for category_dir in "$QM_LOG_DAEMONS" "$QM_LOG_SERVICES" "$QM_LOG_SETTINGS" "$QM_LOG_SYSTEM"; do
|
|
||||||
if [ -d "$category_dir" ]; then
|
|
||||||
for logfile in "$category_dir"/*.log; do
|
|
||||||
if [ -f "$logfile" ]; then
|
|
||||||
# Check file size in KB
|
|
||||||
file_size_kb=$(du -k "$logfile" 2>/dev/null | cut -f1)
|
|
||||||
|
|
||||||
if [ "${file_size_kb:-0}" -gt $CLEANUP_LOG_SIZE ]; then
|
|
||||||
log_cleanup "Rotating large log file: $(basename "$logfile") (${file_size_kb}KB)"
|
|
||||||
qm_rotate_log "$logfile"
|
|
||||||
files_cleaned=$((files_cleaned + 1))
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Additional cleanup: remove empty log files
|
|
||||||
empty_logs=$(find "$QM_LOG_BASE" -name "*.log" -type f -size 0 2>/dev/null)
|
|
||||||
for empty_log in $empty_logs; do
|
|
||||||
rm -f "$empty_log" 2>/dev/null
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
files_cleaned=$((files_cleaned + 1))
|
|
||||||
log_cleanup "Removed empty log file: $(basename "$empty_log")"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Log cleanup summary
|
|
||||||
if [ $files_cleaned -gt 0 ]; then
|
|
||||||
log_cleanup "Cleanup completed: $files_cleaned files processed, ${space_freed}KB freed"
|
|
||||||
else
|
|
||||||
log_cleanup "Cleanup completed: no files needed cleaning"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if we should run cleanup based on disk usage
|
|
||||||
check_disk_usage() {
|
|
||||||
# Check /tmp usage (OpenWrt compatible)
|
|
||||||
local tmp_usage=""
|
|
||||||
|
|
||||||
# Try df first (most common)
|
|
||||||
if command -v df >/dev/null 2>&1; then
|
|
||||||
tmp_usage=$(df /tmp 2>/dev/null | awk 'NR==2 {print $5}' | tr -d '%')
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If we got a valid percentage and it's high, force cleanup
|
|
||||||
if [ -n "$tmp_usage" ] && [ "$tmp_usage" -gt 80 ]; then
|
|
||||||
log_cleanup "High /tmp usage detected (${tmp_usage}%), forcing cleanup"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always run periodic cleanup
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
if check_disk_usage; then
|
|
||||||
perform_cleanup
|
|
||||||
else
|
|
||||||
log_cleanup "Disk usage check passed, skipping cleanup"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clean up centralized log helper's old logs too
|
|
||||||
qm_cleanup_logs
|
|
||||||
|
|
||||||
log_cleanup "Log cleanup process completed"
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Simple QCAINFO Interpreter
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
QCAINFO_FILE="/www/signal_graphs/qcainfo.json"
|
|
||||||
INTERPRETED_FILE="/tmp/interpreted_result.json"
|
|
||||||
DEBUG_LOG="/tmp/qcainfo_interpreter.log"
|
|
||||||
INTERVAL=15
|
|
||||||
|
|
||||||
# Simple logging function
|
|
||||||
log() {
|
|
||||||
echo "$(date): $1" >> "$DEBUG_LOG"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse QCAINFO output to extract band and EARFCN
|
|
||||||
parse_entry() {
|
|
||||||
local output="$1"
|
|
||||||
local datetime="$2"
|
|
||||||
|
|
||||||
# Extract band and EARFCN using simple grep
|
|
||||||
local band=$(echo "$output" | grep -o 'LTE BAND [0-9]*' | head -1)
|
|
||||||
local earfcn=$(echo "$output" | grep -o '+QCAINFO: "PCC",[0-9]*' | grep -o '[0-9]*' | head -1)
|
|
||||||
local pci=$(echo "$output" | grep -o '+QCAINFO: "PCC",[0-9]*,[0-9]*' | grep -o ',[0-9]*,' | tr -d ',' | head -1)
|
|
||||||
|
|
||||||
# Check for SCC (carrier aggregation)
|
|
||||||
local has_scc=""
|
|
||||||
if echo "$output" | grep -q '+QCAINFO: "SCC"'; then
|
|
||||||
has_scc="yes"
|
|
||||||
else
|
|
||||||
has_scc="no"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "${datetime}|${band}|${earfcn}|${pci}|${has_scc}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compare two entries and generate interpretation
|
|
||||||
generate_interpretation() {
|
|
||||||
local old_entry="$1"
|
|
||||||
local new_entry="$2"
|
|
||||||
|
|
||||||
# Parse entries
|
|
||||||
local old_datetime=$(echo "$old_entry" | cut -d'|' -f1)
|
|
||||||
local old_band=$(echo "$old_entry" | cut -d'|' -f2)
|
|
||||||
local old_earfcn=$(echo "$old_entry" | cut -d'|' -f3)
|
|
||||||
local old_pci=$(echo "$old_entry" | cut -d'|' -f4)
|
|
||||||
local old_scc=$(echo "$old_entry" | cut -d'|' -f5)
|
|
||||||
|
|
||||||
local new_datetime=$(echo "$new_entry" | cut -d'|' -f1)
|
|
||||||
local new_band=$(echo "$new_entry" | cut -d'|' -f2)
|
|
||||||
local new_earfcn=$(echo "$new_entry" | cut -d'|' -f3)
|
|
||||||
local new_pci=$(echo "$new_entry" | cut -d'|' -f4)
|
|
||||||
local new_scc=$(echo "$new_entry" | cut -d'|' -f5)
|
|
||||||
|
|
||||||
local time_only=$(echo "$new_datetime" | awk '{print $2}' | cut -d: -f1,2)
|
|
||||||
local interpretation=""
|
|
||||||
|
|
||||||
# Check for band change
|
|
||||||
if [ "$old_band" != "$new_band" ]; then
|
|
||||||
interpretation="${interpretation}At ${time_only}, your modem changed primary band from ${old_band} to ${new_band}. "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for EARFCN change
|
|
||||||
if [ "$old_earfcn" != "$new_earfcn" ]; then
|
|
||||||
interpretation="${interpretation}At ${time_only}, your modem changed primary EARFCN from ${old_earfcn} to ${new_earfcn}. "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for PCI change
|
|
||||||
if [ "$old_pci" != "$new_pci" ]; then
|
|
||||||
interpretation="${interpretation}At ${time_only}, your modem changed primary PCI from ${old_pci} to ${new_pci}. "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for carrier aggregation changes
|
|
||||||
if [ "$old_scc" = "no" ] && [ "$new_scc" = "yes" ]; then
|
|
||||||
interpretation="${interpretation}At ${time_only}, your modem activated carrier aggregation. "
|
|
||||||
elif [ "$old_scc" = "yes" ] && [ "$new_scc" = "no" ]; then
|
|
||||||
interpretation="${interpretation}At ${time_only}, your modem deactivated carrier aggregation. "
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$interpretation"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add interpretation to JSON file without jq
|
|
||||||
add_interpretation() {
|
|
||||||
local interpretation="$1"
|
|
||||||
local datetime="$2"
|
|
||||||
|
|
||||||
if [ -z "$interpretation" ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Initialize file if it doesn't exist
|
|
||||||
if [ ! -f "$INTERPRETED_FILE" ]; then
|
|
||||||
echo "[]" > "$INTERPRETED_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read existing content
|
|
||||||
local existing_content=$(cat "$INTERPRETED_FILE")
|
|
||||||
|
|
||||||
# Escape quotes in interpretation
|
|
||||||
local escaped_interpretation=$(echo "$interpretation" | sed 's/"/\\"/g')
|
|
||||||
|
|
||||||
# Create new entry
|
|
||||||
local new_entry="{\"datetime\":\"$datetime\",\"interpretation\":\"$escaped_interpretation\"}"
|
|
||||||
|
|
||||||
# Add to array
|
|
||||||
if [ "$existing_content" = "[]" ]; then
|
|
||||||
echo "[$new_entry]" > "$INTERPRETED_FILE"
|
|
||||||
else
|
|
||||||
# Remove closing bracket, add comma and new entry
|
|
||||||
echo "$existing_content" | sed 's/]$//' > "$INTERPRETED_FILE.tmp"
|
|
||||||
echo ",$new_entry]" >> "$INTERPRETED_FILE.tmp"
|
|
||||||
mv "$INTERPRETED_FILE.tmp" "$INTERPRETED_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Added interpretation: $interpretation"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main processing function
|
|
||||||
process_qcainfo() {
|
|
||||||
if [ ! -f "$QCAINFO_FILE" ]; then
|
|
||||||
log "QCAINFO file not found: $QCAINFO_FILE"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get total entries
|
|
||||||
local total_entries=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
if [ -z "$total_entries" ] || [ "$total_entries" = "null" ] || [ "$total_entries" -lt 2 ]; then
|
|
||||||
log "Not enough entries to compare (need at least 2, found: $total_entries)"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Found $total_entries entries in QCAINFO file"
|
|
||||||
|
|
||||||
# Get last two entries
|
|
||||||
local last_entry=$(jq -r '.[-1]' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
local second_last_entry=$(jq -r '.[-2]' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
|
|
||||||
if [ "$last_entry" = "null" ] || [ "$second_last_entry" = "null" ]; then
|
|
||||||
log "Failed to get last two entries"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract data from JSON entries
|
|
||||||
local last_datetime=$(echo "$last_entry" | jq -r '.datetime')
|
|
||||||
local last_output=$(echo "$last_entry" | jq -r '.output')
|
|
||||||
local second_datetime=$(echo "$second_last_entry" | jq -r '.datetime')
|
|
||||||
local second_output=$(echo "$second_last_entry" | jq -r '.output')
|
|
||||||
|
|
||||||
log "Comparing entries: $second_datetime vs $last_datetime"
|
|
||||||
|
|
||||||
# Parse entries
|
|
||||||
local parsed_second=$(parse_entry "$second_output" "$second_datetime")
|
|
||||||
local parsed_last=$(parse_entry "$last_output" "$last_datetime")
|
|
||||||
|
|
||||||
log "Parsed second: $parsed_second"
|
|
||||||
log "Parsed last: $parsed_last"
|
|
||||||
|
|
||||||
# Generate interpretation
|
|
||||||
local interpretation=$(generate_interpretation "$parsed_second" "$parsed_last")
|
|
||||||
|
|
||||||
if [ -n "$interpretation" ]; then
|
|
||||||
add_interpretation "$interpretation" "$last_datetime"
|
|
||||||
log "Generated interpretation for $last_datetime"
|
|
||||||
else
|
|
||||||
log "No changes detected between $second_datetime and $last_datetime"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Initialize
|
|
||||||
log "QCAINFO Interpreter started (PID: $$)"
|
|
||||||
|
|
||||||
# Initialize interpreted results file
|
|
||||||
if [ ! -f "$INTERPRETED_FILE" ]; then
|
|
||||||
echo "[]" > "$INTERPRETED_FILE"
|
|
||||||
log "Initialized interpreted results file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Process all existing data once at startup
|
|
||||||
log "Processing all existing QCAINFO data..."
|
|
||||||
if [ -f "$QCAINFO_FILE" ]; then
|
|
||||||
total=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
if [ "$total" -gt 1 ]; then
|
|
||||||
# Process all consecutive pairs
|
|
||||||
i=1
|
|
||||||
while [ $i -lt $total ]; do
|
|
||||||
prev_entry=$(jq -r ".[$((i-1))]" "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
curr_entry=$(jq -r ".[$i]" "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
|
|
||||||
if [ "$prev_entry" != "null" ] && [ "$curr_entry" != "null" ]; then
|
|
||||||
prev_datetime=$(echo "$prev_entry" | jq -r '.datetime')
|
|
||||||
prev_output=$(echo "$prev_entry" | jq -r '.output')
|
|
||||||
curr_datetime=$(echo "$curr_entry" | jq -r '.datetime')
|
|
||||||
curr_output=$(echo "$curr_entry" | jq -r '.output')
|
|
||||||
|
|
||||||
parsed_prev=$(parse_entry "$prev_output" "$prev_datetime")
|
|
||||||
parsed_curr=$(parse_entry "$curr_output" "$curr_datetime")
|
|
||||||
|
|
||||||
interpretation=$(generate_interpretation "$parsed_prev" "$parsed_curr")
|
|
||||||
|
|
||||||
if [ -n "$interpretation" ]; then
|
|
||||||
add_interpretation "$interpretation" "$curr_datetime"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
i=$((i + 1))
|
|
||||||
done
|
|
||||||
log "Completed processing all existing data ($total entries)"
|
|
||||||
else
|
|
||||||
log "Not enough existing data to process"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remember last processed entry count
|
|
||||||
last_count=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
|
|
||||||
# Main monitoring loop
|
|
||||||
log "Starting continuous monitoring (checking every $INTERVAL seconds)"
|
|
||||||
while true; do
|
|
||||||
sleep "$INTERVAL"
|
|
||||||
|
|
||||||
current_count=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
|
|
||||||
if [ "$current_count" -gt "$last_count" ]; then
|
|
||||||
log "New entries detected: $last_count -> $current_count"
|
|
||||||
process_qcainfo
|
|
||||||
last_count="$current_count"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -164,23 +164,7 @@ process_all_metrics() {
|
|||||||
"$logfile" > "$temp_file" 2>/dev/null && mv "$temp_file" "$logfile"
|
"$logfile" > "$temp_file" 2>/dev/null && mv "$temp_file" "$logfile"
|
||||||
chmod 644 "$logfile"
|
chmod 644 "$logfile"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 0.5
|
|
||||||
|
|
||||||
# QCAINFO with time stamp
|
|
||||||
local usage_output=$(execute_at_command "AT+QCAINFO")
|
|
||||||
if [ -n "$usage_output" ] && echo "$usage_output" | grep -q "QCAINFO"; then
|
|
||||||
local logfile="$LOGDIR/qcainfo.json"
|
|
||||||
[ ! -s "$logfile" ] && echo "[]" > "$logfile"
|
|
||||||
|
|
||||||
local temp_file="${logfile}.tmp.$$"
|
|
||||||
jq --arg dt "$timestamp" \
|
|
||||||
--arg out "$usage_output" \
|
|
||||||
'. + [{"datetime": $dt, "output": $out}] | .[-'"$MAX_ENTRIES"':]' \
|
|
||||||
"$logfile" > "$temp_file" 2>/dev/null && mv "$temp_file" "$logfile"
|
|
||||||
chmod 644 "$logfile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Release token
|
# Release token
|
||||||
release_token "$metrics_id"
|
release_token "$metrics_id"
|
||||||
logger -t at_queue -p daemon.info "Metrics processing completed"
|
logger -t at_queue -p daemon.info "Metrics processing completed"
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Memory Daemon - Monitors system memory usage and writes to JSON file
|
|
||||||
# This daemon only runs when memory monitoring is enabled via settings
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Ensure PATH for OpenWrt/BusyBox
|
|
||||||
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
|
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
TMP_DIR="/tmp/quecmanager"
|
|
||||||
OUT_JSON="$TMP_DIR/memory.json"
|
|
||||||
PID_FILE="$TMP_DIR/memory_daemon.pid"
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/memory_settings.conf"
|
|
||||||
[ -f "$CONFIG_FILE" ] || CONFIG_FILE="/tmp/quecmanager/settings/memory_settings.conf"
|
|
||||||
DEFAULT_INTERVAL=1
|
|
||||||
SCRIPT_NAME="memory_daemon"
|
|
||||||
|
|
||||||
# Ensure temp directory exists
|
|
||||||
ensure_tmp_dir() {
|
|
||||||
[ -d "$TMP_DIR" ] || mkdir -p "$TMP_DIR" || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Logging function
|
|
||||||
log() {
|
|
||||||
qm_log_info "daemon" "$SCRIPT_NAME" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if this daemon instance is already running
|
|
||||||
daemon_is_running() {
|
|
||||||
if [ -f "$PID_FILE" ]; then
|
|
||||||
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
|
||||||
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
|
|
||||||
# Verify it's actually our daemon by checking process cmdline
|
|
||||||
if [ -r "/proc/$pid/cmdline" ] && grep -q "memory_daemon.sh" "/proc/$pid/cmdline" 2>/dev/null; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# PID file is stale, remove it
|
|
||||||
rm -f "$PID_FILE" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write our PID to file
|
|
||||||
write_pid() {
|
|
||||||
echo "$$" > "$PID_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cleanup function
|
|
||||||
cleanup() {
|
|
||||||
rm -f "$PID_FILE" 2>/dev/null || true
|
|
||||||
log "Memory daemon stopped"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create default config if none exists
|
|
||||||
create_default_config() {
|
|
||||||
local primary_config="/etc/quecmanager/settings/memory_settings.conf"
|
|
||||||
local fallback_config="/tmp/quecmanager/settings/memory_settings.conf"
|
|
||||||
|
|
||||||
if [ ! -f "$primary_config" ] && [ ! -f "$fallback_config" ]; then
|
|
||||||
log "No config file found, creating default configuration"
|
|
||||||
|
|
||||||
# Try primary location first
|
|
||||||
if mkdir -p "/etc/quecmanager/settings" 2>/dev/null; then
|
|
||||||
{
|
|
||||||
echo "MEMORY_ENABLED=false"
|
|
||||||
echo "MEMORY_INTERVAL=1"
|
|
||||||
} > "$primary_config" 2>/dev/null && {
|
|
||||||
chmod 644 "$primary_config" 2>/dev/null || true
|
|
||||||
CONFIG_FILE="$primary_config"
|
|
||||||
log "Created default config at $primary_config"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback to tmp location
|
|
||||||
mkdir -p "/tmp/quecmanager/settings" 2>/dev/null || true
|
|
||||||
{
|
|
||||||
echo "MEMORY_ENABLED=false"
|
|
||||||
echo "MEMORY_INTERVAL=1"
|
|
||||||
} > "$fallback_config" && {
|
|
||||||
chmod 644 "$fallback_config" 2>/dev/null || true
|
|
||||||
CONFIG_FILE="$fallback_config"
|
|
||||||
log "Created default config at $fallback_config"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Failed to create default config file"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read configuration from file
|
|
||||||
read_config() {
|
|
||||||
ENABLED="false"
|
|
||||||
INTERVAL="$DEFAULT_INTERVAL"
|
|
||||||
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
MEMORY_ENABLED=$(grep -E "^MEMORY_ENABLED=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r' | tr -d '"')
|
|
||||||
MEMORY_INTERVAL=$(grep -E "^MEMORY_INTERVAL=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r')
|
|
||||||
|
|
||||||
case "${MEMORY_ENABLED:-}" in
|
|
||||||
true|1|on|yes|enabled) ENABLED="true" ;;
|
|
||||||
*) ENABLED="false" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if echo "${MEMORY_INTERVAL:-}" | grep -qE '^[0-9]+$'; then
|
|
||||||
if [ "$MEMORY_INTERVAL" -ge 1 ] && [ "$MEMORY_INTERVAL" -le 10 ]; then
|
|
||||||
INTERVAL="$MEMORY_INTERVAL"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write JSON data atomically
|
|
||||||
write_json_atomic() {
|
|
||||||
local json_data="$1"
|
|
||||||
local tmpfile="$(mktemp "$TMP_DIR/memory.XXXXXX" 2>/dev/null || echo "$TMP_DIR/memory.tmp.$$")"
|
|
||||||
|
|
||||||
if [ -n "$tmpfile" ] && printf '%s' "$json_data" > "$tmpfile" 2>/dev/null; then
|
|
||||||
mv "$tmpfile" "$OUT_JSON" 2>/dev/null || {
|
|
||||||
# Fallback if move fails
|
|
||||||
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
|
|
||||||
rm -f "$tmpfile" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# Direct write fallback
|
|
||||||
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
|
|
||||||
rm -f "$tmpfile" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution starts here
|
|
||||||
ensure_tmp_dir
|
|
||||||
log "Starting memory daemon (PID: $$)"
|
|
||||||
|
|
||||||
# Check if already running
|
|
||||||
if daemon_is_running; then
|
|
||||||
log "Memory daemon already running, exiting"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create default config if needed
|
|
||||||
create_default_config
|
|
||||||
|
|
||||||
# Set up signal handlers
|
|
||||||
trap cleanup EXIT INT TERM
|
|
||||||
write_pid
|
|
||||||
|
|
||||||
# Main monitoring loop
|
|
||||||
while true; do
|
|
||||||
read_config
|
|
||||||
|
|
||||||
# Exit if disabled
|
|
||||||
if [ "$ENABLED" != "true" ]; then
|
|
||||||
log "Memory monitoring disabled in config, exiting"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get current timestamp
|
|
||||||
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
||||||
|
|
||||||
# Get memory information using /proc/meminfo (most reliable method)
|
|
||||||
if [ -r "/proc/meminfo" ]; then
|
|
||||||
# Extract values from /proc/meminfo (values are in kB)
|
|
||||||
TOTAL_KB=$(grep "^MemTotal:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
|
||||||
AVAIL_KB=$(grep "^MemAvailable:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
|
||||||
FREE_KB=$(grep "^MemFree:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
|
||||||
|
|
||||||
# If MemAvailable is not available (older kernels), estimate it
|
|
||||||
if [ "$AVAIL_KB" = "0" ]; then
|
|
||||||
CACHED_KB=$(grep "^Cached:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
|
||||||
BUFFERS_KB=$(grep "^Buffers:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
|
|
||||||
AVAIL_KB=$((FREE_KB + CACHED_KB + BUFFERS_KB))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Convert to bytes (multiply by 1024)
|
|
||||||
TOTAL_BYTES=$((TOTAL_KB * 1024))
|
|
||||||
AVAIL_BYTES=$((AVAIL_KB * 1024))
|
|
||||||
USED_BYTES=$((TOTAL_BYTES - AVAIL_BYTES))
|
|
||||||
|
|
||||||
json="{\"total\": $TOTAL_BYTES, \"used\": $USED_BYTES, \"available\": $AVAIL_BYTES, \"timestamp\": \"$ts\"}"
|
|
||||||
else
|
|
||||||
# Fallback if /proc/meminfo is not available
|
|
||||||
log "Warning: /proc/meminfo not readable, using error response"
|
|
||||||
json="{\"total\": 0, \"used\": 0, \"available\": 0, \"timestamp\": \"$ts\", \"error\": \"meminfo_unavailable\"}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Write the JSON data
|
|
||||||
write_json_atomic "$json"
|
|
||||||
log "Updated memory data: total=${TOTAL_KB:-0}KB, used=${USED_BYTES:-0}B, available=${AVAIL_KB:-0}KB"
|
|
||||||
|
|
||||||
# Sleep for the configured interval
|
|
||||||
sleep "$INTERVAL"
|
|
||||||
done
|
|
||||||
@@ -1,372 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Network Insights Interpreter Service
|
|
||||||
# Monitors qcainfo.json and generates network event interpretations
|
|
||||||
# OpenWrt/BusyBox compatible version
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
QCAINFO_FILE="/www/signal_graphs/qcainfo.json"
|
|
||||||
INTERPRETED_FILE="/tmp/interpreted_result.json"
|
|
||||||
LAST_ENTRY_FILE="/tmp/last_qcainfo_entry.json"
|
|
||||||
LOCKFILE="/tmp/network_interpreter.lock"
|
|
||||||
MAX_INTERPRETATIONS=50
|
|
||||||
|
|
||||||
# Logging function (OpenWrt compatible)
|
|
||||||
log_message() {
|
|
||||||
if command -v logger >/dev/null 2>&1; then
|
|
||||||
logger -t network_interpreter -p daemon.info "$1"
|
|
||||||
else
|
|
||||||
# Use simpler date format for BusyBox
|
|
||||||
echo "$(date) [network_interpreter] $1" >&2
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Convert datetime to timestamp (OpenWrt/BusyBox compatible)
|
|
||||||
datetime_to_timestamp() {
|
|
||||||
local datetime="$1"
|
|
||||||
# Try GNU date first, fallback to string comparison for BusyBox
|
|
||||||
if date -d "$datetime" +%s >/dev/null 2>&1; then
|
|
||||||
date -d "$datetime" +%s
|
|
||||||
else
|
|
||||||
# For BusyBox, just return the datetime string for string comparison
|
|
||||||
# This is less precise but works for sequential comparison
|
|
||||||
echo "$datetime"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compare timestamps/datetime strings (OpenWrt compatible)
|
|
||||||
is_datetime_newer() {
|
|
||||||
local datetime1="$1"
|
|
||||||
local datetime2="$2"
|
|
||||||
|
|
||||||
local ts1=$(datetime_to_timestamp "$datetime1")
|
|
||||||
local ts2=$(datetime_to_timestamp "$datetime2")
|
|
||||||
|
|
||||||
# If we got numeric timestamps, compare numerically
|
|
||||||
if [ "$ts1" -eq "$ts1" ] 2>/dev/null && [ "$ts2" -eq "$ts2" ] 2>/dev/null; then
|
|
||||||
[ "$ts1" -gt "$ts2" ]
|
|
||||||
else
|
|
||||||
# Fall back to string comparison (works for ISO format)
|
|
||||||
[ "$datetime1" \> "$datetime2" ]
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse QCAINFO output to extract band information
|
|
||||||
parse_qcainfo_bands() {
|
|
||||||
local output="$1"
|
|
||||||
|
|
||||||
# Clean up the output - remove escape sequences and extra characters
|
|
||||||
local clean_output=$(echo "$output" | tr -d '\r' | sed 's/\\r//g; s/\\n/\n/g')
|
|
||||||
|
|
||||||
# Extract all band information from QCAINFO lines
|
|
||||||
echo "$clean_output" | grep "+QCAINFO:" | while IFS= read -r line; do
|
|
||||||
if echo "$line" | grep -q "LTE BAND"; then
|
|
||||||
band=$(echo "$line" | sed -n 's/.*"LTE BAND \([0-9][0-9]*\)".*/B\1/p')
|
|
||||||
if [ -n "$band" ]; then
|
|
||||||
echo "LTE:$band"
|
|
||||||
fi
|
|
||||||
elif echo "$line" | grep -q "NR5G BAND"; then
|
|
||||||
band=$(echo "$line" | sed -n 's/.*"NR5G BAND \([0-9][0-9]*\)".*/N\1/p')
|
|
||||||
if [ -n "$band" ]; then
|
|
||||||
echo "NR5G:$band"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get network mode from bands
|
|
||||||
get_network_mode() {
|
|
||||||
local bands="$1"
|
|
||||||
local has_lte=false
|
|
||||||
local has_nr5g=false
|
|
||||||
|
|
||||||
if echo "$bands" | grep -q "LTE:"; then
|
|
||||||
has_lte=true
|
|
||||||
fi
|
|
||||||
if echo "$bands" | grep -q "NR5G:"; then
|
|
||||||
has_nr5g=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$has_lte" = true ] && [ "$has_nr5g" = true ]; then
|
|
||||||
echo "NSA"
|
|
||||||
elif [ "$has_lte" = true ]; then
|
|
||||||
echo "LTE"
|
|
||||||
elif [ "$has_nr5g" = true ]; then
|
|
||||||
echo "SA"
|
|
||||||
else
|
|
||||||
echo "NO_SIGNAL"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get band list from parsed bands
|
|
||||||
get_band_list() {
|
|
||||||
local bands="$1"
|
|
||||||
if [ -z "$bands" ]; then
|
|
||||||
echo ""
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
echo "$bands" | sed 's/LTE://g; s/NR5G://g' | sort -u | tr '\n' ',' | sed 's/,$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get carrier count
|
|
||||||
get_carrier_count() {
|
|
||||||
local bands="$1"
|
|
||||||
if [ -z "$bands" ]; then
|
|
||||||
echo "0"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
echo "$bands" | wc -l
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compare two band configurations and generate interpretation
|
|
||||||
compare_configurations() {
|
|
||||||
local base_output="$1"
|
|
||||||
local new_output="$2"
|
|
||||||
local base_datetime="$3"
|
|
||||||
local new_datetime="$4"
|
|
||||||
|
|
||||||
# Parse both configurations
|
|
||||||
local base_bands=$(parse_qcainfo_bands "$base_output")
|
|
||||||
local new_bands=$(parse_qcainfo_bands "$new_output")
|
|
||||||
|
|
||||||
local base_mode=$(get_network_mode "$base_bands")
|
|
||||||
local new_mode=$(get_network_mode "$new_bands")
|
|
||||||
|
|
||||||
local base_band_list=$(get_band_list "$base_bands")
|
|
||||||
local new_band_list=$(get_band_list "$new_bands")
|
|
||||||
|
|
||||||
local base_carrier_count=$(get_carrier_count "$base_bands")
|
|
||||||
local new_carrier_count=$(get_carrier_count "$new_bands")
|
|
||||||
|
|
||||||
local interpretations=""
|
|
||||||
|
|
||||||
# Check for no signal condition
|
|
||||||
if [ "$new_mode" = "NO_SIGNAL" ]; then
|
|
||||||
if [ "$base_mode" != "NO_SIGNAL" ]; then
|
|
||||||
interpretations="Signal lost - No cellular connection detected"
|
|
||||||
fi
|
|
||||||
# Check if signal was restored
|
|
||||||
elif [ "$base_mode" = "NO_SIGNAL" ] && [ "$new_mode" != "NO_SIGNAL" ]; then
|
|
||||||
interpretations="Signal restored - Connected to $new_mode network"
|
|
||||||
if [ -n "$new_band_list" ]; then
|
|
||||||
interpretations="$interpretations ($new_band_list)"
|
|
||||||
fi
|
|
||||||
# Check if CA was activated immediately upon signal restoration
|
|
||||||
if [ "$new_carrier_count" -gt 1 ]; then
|
|
||||||
interpretations="$interpretations; Carrier Aggregation activated - Now using $new_carrier_count carriers"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Network mode changes
|
|
||||||
if [ "$base_mode" != "$new_mode" ]; then
|
|
||||||
case "$new_mode" in
|
|
||||||
"LTE")
|
|
||||||
if [ "$base_mode" = "NSA" ]; then
|
|
||||||
interpretations="Network mode changed from NSA to LTE-only"
|
|
||||||
elif [ "$base_mode" = "SA" ]; then
|
|
||||||
interpretations="Network mode changed from 5G SA to LTE"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"SA")
|
|
||||||
if [ "$base_mode" = "LTE" ]; then
|
|
||||||
interpretations="Network mode changed from LTE to 5G SA"
|
|
||||||
elif [ "$base_mode" = "NSA" ]; then
|
|
||||||
interpretations="Network mode changed from NSA to 5G SA"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"NSA")
|
|
||||||
if [ "$base_mode" = "LTE" ]; then
|
|
||||||
interpretations="Network mode changed from LTE to NSA"
|
|
||||||
elif [ "$base_mode" = "SA" ]; then
|
|
||||||
interpretations="Network mode changed from 5G SA to NSA"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Band changes
|
|
||||||
if [ "$base_band_list" != "$new_band_list" ]; then
|
|
||||||
if [ -n "$interpretations" ]; then
|
|
||||||
interpretations="$interpretations; "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Find added and removed bands
|
|
||||||
local added_bands=""
|
|
||||||
local removed_bands=""
|
|
||||||
|
|
||||||
# Check for new bands
|
|
||||||
for band in $(echo "$new_band_list" | tr ',' ' '); do
|
|
||||||
if [ -n "$band" ] && ! echo "$base_band_list" | grep -q "$band"; then
|
|
||||||
if [ -n "$added_bands" ]; then
|
|
||||||
added_bands="$added_bands, $band"
|
|
||||||
else
|
|
||||||
added_bands="$band"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Check for removed bands
|
|
||||||
for band in $(echo "$base_band_list" | tr ',' ' '); do
|
|
||||||
if [ -n "$band" ] && ! echo "$new_band_list" | grep -q "$band"; then
|
|
||||||
if [ -n "$removed_bands" ]; then
|
|
||||||
removed_bands="$removed_bands, $band"
|
|
||||||
else
|
|
||||||
removed_bands="$band"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -n "$added_bands" ] && [ -n "$removed_bands" ]; then
|
|
||||||
interpretations="${interpretations}Band configuration changed - Added: $added_bands, Removed: $removed_bands"
|
|
||||||
elif [ -n "$added_bands" ]; then
|
|
||||||
interpretations="${interpretations}New bands added: $added_bands"
|
|
||||||
elif [ -n "$removed_bands" ]; then
|
|
||||||
interpretations="${interpretations}Bands removed: $removed_bands"
|
|
||||||
else
|
|
||||||
interpretations="${interpretations}Band sequence changed from ($base_band_list) to ($new_band_list)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Carrier Aggregation changes
|
|
||||||
if [ "$base_carrier_count" != "$new_carrier_count" ]; then
|
|
||||||
if [ -n "$interpretations" ]; then
|
|
||||||
interpretations="$interpretations; "
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$new_carrier_count" -gt 1 ] && [ "$base_carrier_count" -le 1 ]; then
|
|
||||||
interpretations="${interpretations}Carrier Aggregation activated - Now using $new_carrier_count carriers"
|
|
||||||
elif [ "$new_carrier_count" -le 1 ] && [ "$base_carrier_count" -gt 1 ]; then
|
|
||||||
interpretations="${interpretations}Carrier Aggregation deactivated - Single carrier mode"
|
|
||||||
elif [ "$new_carrier_count" -gt "$base_carrier_count" ]; then
|
|
||||||
interpretations="${interpretations}Additional carriers aggregated - Carriers increased from $base_carrier_count to $new_carrier_count"
|
|
||||||
elif [ "$new_carrier_count" -lt "$base_carrier_count" ]; then
|
|
||||||
interpretations="${interpretations}Carriers reduced from $base_carrier_count to $new_carrier_count"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return interpretation if any changes detected
|
|
||||||
if [ -n "$interpretations" ]; then
|
|
||||||
echo "$interpretations"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add interpretation to JSON file
|
|
||||||
add_interpretation() {
|
|
||||||
local datetime="$1"
|
|
||||||
local interpretation="$2"
|
|
||||||
|
|
||||||
# Initialize file if it doesn't exist
|
|
||||||
if [ ! -f "$INTERPRETED_FILE" ]; then
|
|
||||||
echo "[]" > "$INTERPRETED_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add new interpretation using jq
|
|
||||||
local temp_file="${INTERPRETED_FILE}.tmp.$$"
|
|
||||||
jq --arg dt "$datetime" \
|
|
||||||
--arg interp "$interpretation" \
|
|
||||||
'. + [{"datetime": $dt, "interpretation": $interp}] | .[-'"$MAX_INTERPRETATIONS"':]' \
|
|
||||||
"$INTERPRETED_FILE" > "$temp_file" 2>/dev/null && mv "$temp_file" "$INTERPRETED_FILE"
|
|
||||||
|
|
||||||
chmod 644 "$INTERPRETED_FILE"
|
|
||||||
log_message "Added interpretation: $interpretation"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process QCAINFO entries and generate interpretations
|
|
||||||
process_qcainfo_data() {
|
|
||||||
if [ ! -f "$QCAINFO_FILE" ]; then
|
|
||||||
log_message "QCAINFO file not found: $QCAINFO_FILE"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get total number of entries
|
|
||||||
local total_entries=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null || echo "0")
|
|
||||||
|
|
||||||
if [ "$total_entries" -lt 2 ]; then
|
|
||||||
log_message "Not enough entries to compare ($total_entries)"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the last processed entry timestamp
|
|
||||||
local last_processed=""
|
|
||||||
if [ -f "$LAST_ENTRY_FILE" ]; then
|
|
||||||
last_processed=$(cat "$LAST_ENTRY_FILE" 2>/dev/null)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Process entries sequentially
|
|
||||||
local i=0
|
|
||||||
while [ "$i" -lt $((total_entries - 1)) ]; do
|
|
||||||
local base_entry=$(jq -r ".[$i]" "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
local next_entry=$(jq -r ".[$(($i + 1))]" "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
|
|
||||||
local base_datetime=$(echo "$base_entry" | jq -r '.datetime' 2>/dev/null)
|
|
||||||
local next_datetime=$(echo "$next_entry" | jq -r '.datetime' 2>/dev/null)
|
|
||||||
local base_output=$(echo "$base_entry" | jq -r '.output' 2>/dev/null)
|
|
||||||
local next_output=$(echo "$next_entry" | jq -r '.output' 2>/dev/null)
|
|
||||||
|
|
||||||
# Skip if this entry was already processed
|
|
||||||
if [ -n "$last_processed" ] && [ "$next_datetime" = "$last_processed" ]; then
|
|
||||||
i=$((i + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only process entries after the last processed one
|
|
||||||
if [ -n "$last_processed" ]; then
|
|
||||||
if ! is_datetime_newer "$next_datetime" "$last_processed"; then
|
|
||||||
i=$((i + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Compare configurations and generate interpretation
|
|
||||||
local interpretation=$(compare_configurations "$base_output" "$next_output" "$base_datetime" "$next_datetime")
|
|
||||||
|
|
||||||
if [ -n "$interpretation" ]; then
|
|
||||||
add_interpretation "$next_datetime" "$interpretation"
|
|
||||||
fi
|
|
||||||
|
|
||||||
i=$((i + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Update last processed entry
|
|
||||||
if [ "$total_entries" -gt 0 ]; then
|
|
||||||
local last_datetime=$(jq -r '.[-1].datetime' "$QCAINFO_FILE" 2>/dev/null)
|
|
||||||
echo "$last_datetime" > "$LAST_ENTRY_FILE"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check for new entries every 61 seconds
|
|
||||||
monitor_qcainfo() {
|
|
||||||
log_message "Starting network insights interpreter monitoring"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
# Acquire lock (OpenWrt compatible)
|
|
||||||
if (set -C; echo $$ > "$LOCKFILE") 2>/dev/null; then
|
|
||||||
trap 'rm -f "$LOCKFILE"; exit' INT TERM EXIT
|
|
||||||
|
|
||||||
process_qcainfo_data
|
|
||||||
|
|
||||||
# Release lock
|
|
||||||
rm -f "$LOCKFILE"
|
|
||||||
trap - INT TERM EXIT
|
|
||||||
else
|
|
||||||
log_message "Another instance is running, skipping this cycle"
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep 61
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
case "${1:-monitor}" in
|
|
||||||
"monitor")
|
|
||||||
monitor_qcainfo
|
|
||||||
;;
|
|
||||||
"process")
|
|
||||||
process_qcainfo_data
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {monitor|process}"
|
|
||||||
echo " monitor - Run continuous monitoring (default)"
|
|
||||||
echo " process - Process current data once"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Ensure PATH for OpenWrt/BusyBox
|
|
||||||
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
|
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
TMP_DIR="/tmp/quecmanager"
|
|
||||||
OUT_JSON="$TMP_DIR/ping_latency.json"
|
|
||||||
PID_FILE="$TMP_DIR/ping_daemon.pid"
|
|
||||||
CONFIG_FILE="/etc/quecmanager/settings/ping_settings.conf"
|
|
||||||
[ -f "$CONFIG_FILE" ] || CONFIG_FILE="/tmp/quecmanager/settings/ping_settings.conf"
|
|
||||||
DEFAULT_HOST="8.8.8.8"
|
|
||||||
DEFAULT_INTERVAL=5
|
|
||||||
SCRIPT_NAME="ping_daemon"
|
|
||||||
|
|
||||||
ensure_tmp_dir() { [ -d "$TMP_DIR" ] || mkdir -p "$TMP_DIR" || exit 1; }
|
|
||||||
|
|
||||||
log() {
|
|
||||||
qm_log_info "daemon" "$SCRIPT_NAME" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon_is_running() {
|
|
||||||
if [ -f "$PID_FILE" ]; then
|
|
||||||
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
|
||||||
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
|
|
||||||
# Avoid false positive if PID reused
|
|
||||||
if [ -r "/proc/$pid/cmdline" ] && grep -q "ping_daemon.sh" "/proc/$pid/cmdline" 2>/dev/null; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
rm -f "$PID_FILE" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
write_pid() { echo "$$" > "$PID_FILE"; }
|
|
||||||
|
|
||||||
cleanup() { rm -f "$PID_FILE" 2>/dev/null || true; }
|
|
||||||
|
|
||||||
read_config() {
|
|
||||||
ENABLED="true"; HOST="$DEFAULT_HOST"; INTERVAL="$DEFAULT_INTERVAL"
|
|
||||||
if [ -f "$CONFIG_FILE" ]; then
|
|
||||||
PING_ENABLED=$(grep -E "^PING_ENABLED=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
|
|
||||||
PING_HOST=$(grep -E "^PING_HOST=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
|
|
||||||
PING_INTERVAL=$(grep -E "^PING_INTERVAL=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
|
|
||||||
case "${PING_ENABLED:-}" in true|1|on|yes|enabled) ENABLED=true ;; *) ENABLED=false ;; esac
|
|
||||||
[ -n "${PING_HOST:-}" ] && HOST="$PING_HOST"
|
|
||||||
if echo "${PING_INTERVAL:-}" | grep -qE '^[0-9]+$'; then
|
|
||||||
if [ "$PING_INTERVAL" -ge 1 ] && [ "$PING_INTERVAL" -le 3600 ]; then
|
|
||||||
INTERVAL="$PING_INTERVAL"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create default config if none exists
|
|
||||||
create_default_config() {
|
|
||||||
local primary_config="/etc/quecmanager/settings/ping_settings.conf"
|
|
||||||
local fallback_config="/tmp/quecmanager/settings/ping_settings.conf"
|
|
||||||
|
|
||||||
# Check if either config exists
|
|
||||||
if [ -f "$primary_config" ] || [ -f "$fallback_config" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try to create in primary location first
|
|
||||||
if mkdir -p "/etc/quecmanager/settings" 2>/dev/null; then
|
|
||||||
{
|
|
||||||
echo "PING_ENABLED=true"
|
|
||||||
echo "PING_HOST=$DEFAULT_HOST"
|
|
||||||
echo "PING_INTERVAL=$DEFAULT_INTERVAL"
|
|
||||||
} > "$primary_config" 2>/dev/null && {
|
|
||||||
chmod 644 "$primary_config" 2>/dev/null || true
|
|
||||||
CONFIG_FILE="$primary_config"
|
|
||||||
log "Created default config at $primary_config"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback to tmp location
|
|
||||||
mkdir -p "/tmp/quecmanager/settings" 2>/dev/null || true
|
|
||||||
{
|
|
||||||
echo "PING_ENABLED=true"
|
|
||||||
echo "PING_HOST=$DEFAULT_HOST"
|
|
||||||
echo "PING_INTERVAL=$DEFAULT_INTERVAL"
|
|
||||||
} > "$fallback_config" && {
|
|
||||||
chmod 644 "$fallback_config" 2>/dev/null || true
|
|
||||||
CONFIG_FILE="$fallback_config"
|
|
||||||
log "Created default config at $fallback_config"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Failed to create default config file"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
write_json_atomic() {
|
|
||||||
tmpfile="$(mktemp "$TMP_DIR/ping_latency.XXXXXX" 2>/dev/null || true)"
|
|
||||||
if [ -n "${tmpfile:-}" ] && [ -w "$TMP_DIR" ]; then
|
|
||||||
printf '%s' "$1" > "$tmpfile" 2>/dev/null || true
|
|
||||||
mv -f "$tmpfile" "$OUT_JSON" 2>/dev/null || printf '%s' "$1" > "$OUT_JSON"
|
|
||||||
else
|
|
||||||
printf '%s' "$1" > "$OUT_JSON"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_tmp_dir
|
|
||||||
log "Starting ping daemon"
|
|
||||||
if daemon_is_running; then log "Already running"; exit 0; fi
|
|
||||||
|
|
||||||
# Create default config if none exists
|
|
||||||
create_default_config
|
|
||||||
|
|
||||||
trap cleanup EXIT INT TERM
|
|
||||||
write_pid
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
read_config
|
|
||||||
if [ "$ENABLED" != "true" ]; then log "Disabled in config"; exit 0; fi
|
|
||||||
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
||||||
PING_BIN="$(command -v ping || echo /bin/ping)"
|
|
||||||
output="$("$PING_BIN" -c 1 -w 2 "$HOST" 2>/dev/null || true)"
|
|
||||||
if echo "$output" | grep -q "time="; then
|
|
||||||
latency_ms="$(echo "$output" | grep -o 'time=[0-9.]*' | head -n1 | cut -d'=' -f2 | cut -d'.' -f1)"; [ -z "$latency_ms" ] && latency_ms=0
|
|
||||||
json="{\"timestamp\":\"$ts\",\"host\":\"$HOST\",\"latency\":$latency_ms,\"ok\":true}"
|
|
||||||
else
|
|
||||||
json="{\"timestamp\":\"$ts\",\"host\":\"$HOST\",\"latency\":null,\"ok\":false}"
|
|
||||||
fi
|
|
||||||
write_json_atomic "$json"
|
|
||||||
log "Wrote: $json"
|
|
||||||
sleep "$INTERVAL"
|
|
||||||
done
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# QuecManager Centralized Logging Helper
|
|
||||||
# OpenWrt/BusyBox compatible logging system
|
|
||||||
# Usage: source this file and use qm_log function
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Base log directory
|
|
||||||
QM_LOG_BASE="/tmp/quecmanager/logs"
|
|
||||||
|
|
||||||
# Log categories
|
|
||||||
QM_LOG_DAEMONS="$QM_LOG_BASE/daemons"
|
|
||||||
QM_LOG_SERVICES="$QM_LOG_BASE/services"
|
|
||||||
QM_LOG_SETTINGS="$QM_LOG_BASE/settings"
|
|
||||||
QM_LOG_SYSTEM="$QM_LOG_BASE/system"
|
|
||||||
|
|
||||||
# Log levels
|
|
||||||
QM_LOG_ERROR="ERROR"
|
|
||||||
QM_LOG_WARN="WARN"
|
|
||||||
QM_LOG_INFO="INFO"
|
|
||||||
QM_LOG_DEBUG="DEBUG"
|
|
||||||
|
|
||||||
# Maximum log file size (in KB) - keep small for OpenWrt
|
|
||||||
QM_LOG_MAX_SIZE=500
|
|
||||||
|
|
||||||
# Initialize log directories
|
|
||||||
qm_init_logs() {
|
|
||||||
mkdir -p "$QM_LOG_DAEMONS" "$QM_LOG_SERVICES" "$QM_LOG_SETTINGS" "$QM_LOG_SYSTEM" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get log file path based on category and script name
|
|
||||||
qm_get_logfile() {
|
|
||||||
local category="$1"
|
|
||||||
local script_name="$2"
|
|
||||||
|
|
||||||
case "$category" in
|
|
||||||
"daemon"|"daemons")
|
|
||||||
echo "$QM_LOG_DAEMONS/${script_name}.log"
|
|
||||||
;;
|
|
||||||
"service"|"services")
|
|
||||||
echo "$QM_LOG_SERVICES/${script_name}.log"
|
|
||||||
;;
|
|
||||||
"setting"|"settings")
|
|
||||||
echo "$QM_LOG_SETTINGS/${script_name}.log"
|
|
||||||
;;
|
|
||||||
"system")
|
|
||||||
echo "$QM_LOG_SYSTEM/${script_name}.log"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "$QM_LOG_SYSTEM/unknown.log"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Simple log rotation - keep it OpenWrt compatible
|
|
||||||
qm_rotate_log() {
|
|
||||||
local logfile="$1"
|
|
||||||
|
|
||||||
if [ -f "$logfile" ]; then
|
|
||||||
# Get file size in KB (use du for BusyBox compatibility)
|
|
||||||
local size_kb=$(du -k "$logfile" 2>/dev/null | cut -f1)
|
|
||||||
|
|
||||||
if [ "${size_kb:-0}" -gt "$QM_LOG_MAX_SIZE" ]; then
|
|
||||||
# Simple rotation: keep last 2 versions
|
|
||||||
[ -f "${logfile}.1" ] && mv "${logfile}.1" "${logfile}.2" 2>/dev/null || true
|
|
||||||
mv "$logfile" "${logfile}.1" 2>/dev/null || true
|
|
||||||
touch "$logfile" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main logging function
|
|
||||||
# Usage: qm_log "category" "script_name" "level" "message"
|
|
||||||
qm_log() {
|
|
||||||
local category="$1"
|
|
||||||
local script_name="$2"
|
|
||||||
local level="$3"
|
|
||||||
local message="$4"
|
|
||||||
|
|
||||||
# Initialize if needed
|
|
||||||
qm_init_logs
|
|
||||||
|
|
||||||
# Get log file path
|
|
||||||
local logfile=$(qm_get_logfile "$category" "$script_name")
|
|
||||||
|
|
||||||
# Rotate if needed
|
|
||||||
qm_rotate_log "$logfile"
|
|
||||||
|
|
||||||
# Create log entry with OpenWrt compatible date
|
|
||||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S' 2>/dev/null || date)
|
|
||||||
local pid="$$"
|
|
||||||
|
|
||||||
# Write log entry
|
|
||||||
printf '[%s] [%s] [%s] [PID:%s] %s\n' "$timestamp" "$level" "$script_name" "$pid" "$message" >> "$logfile" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# Convenience functions for different log levels
|
|
||||||
qm_log_error() {
|
|
||||||
qm_log "$1" "$2" "$QM_LOG_ERROR" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
qm_log_warn() {
|
|
||||||
qm_log "$1" "$2" "$QM_LOG_WARN" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
qm_log_info() {
|
|
||||||
qm_log "$1" "$2" "$QM_LOG_INFO" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
qm_log_debug() {
|
|
||||||
qm_log "$1" "$2" "$QM_LOG_DEBUG" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cleanup old logs (called periodically)
|
|
||||||
qm_cleanup_logs() {
|
|
||||||
# Remove .2 backup files older than 1 day to save space
|
|
||||||
find "$QM_LOG_BASE" -name "*.2" -type f -mtime +1 -delete 2>/dev/null || true
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,6 @@
|
|||||||
# Updated QuecProfiles daemon with enhanced SA/NSA NR5G band management and TTL support
|
# Updated QuecProfiles daemon with enhanced SA/NSA NR5G band management and TTL support
|
||||||
# Including profile application functions and fixed comparison logic
|
# Including profile application functions and fixed comparison logic
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
QUEUE_DIR="/tmp/at_queue"
|
QUEUE_DIR="/tmp/at_queue"
|
||||||
TOKEN_FILE="$QUEUE_DIR/token"
|
TOKEN_FILE="$QUEUE_DIR/token"
|
||||||
@@ -18,49 +15,25 @@ DEFAULT_CHECK_INTERVAL=60 # Default check interval in seconds
|
|||||||
COMMAND_TIMEOUT=10 # Default timeout for AT commands in seconds
|
COMMAND_TIMEOUT=10 # Default timeout for AT commands in seconds
|
||||||
QUEUE_PRIORITY=3 # Medium-high priority (1 is highest for cell scan)
|
QUEUE_PRIORITY=3 # Medium-high priority (1 is highest for cell scan)
|
||||||
MAX_TOKEN_WAIT=15 # Maximum seconds to wait for token acquisition
|
MAX_TOKEN_WAIT=15 # Maximum seconds to wait for token acquisition
|
||||||
SCRIPT_NAME_LOG="quecprofiles_daemon"
|
|
||||||
|
|
||||||
# Initialize log files and use centralized logging
|
# Initialize log file
|
||||||
mkdir -p "$(dirname "$DEBUG_LOG")" "$(dirname "$DETAILED_LOG")"
|
|
||||||
touch "$DEBUG_LOG" "$DETAILED_LOG"
|
|
||||||
chmod 644 "$DEBUG_LOG" "$DETAILED_LOG"
|
|
||||||
|
|
||||||
# Log startup message using centralized logging
|
|
||||||
qm_log_info "service" "$SCRIPT_NAME_LOG" "Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)"
|
|
||||||
|
|
||||||
# Also maintain file logging for compatibility
|
|
||||||
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DEBUG_LOG"
|
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DEBUG_LOG"
|
||||||
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DETAILED_LOG"
|
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DETAILED_LOG"
|
||||||
|
chmod 644 "$DEBUG_LOG" "$DETAILED_LOG"
|
||||||
|
|
||||||
# Function to log messages - now uses centralized logging
|
# Function to log messages
|
||||||
log_message() {
|
log_message() {
|
||||||
local message="$1"
|
local message="$1"
|
||||||
local level="${2:-info}"
|
local level="${2:-info}"
|
||||||
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
|
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
# Use centralized logging
|
# Log to system log
|
||||||
case "$level" in
|
|
||||||
"error")
|
|
||||||
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"warn")
|
|
||||||
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"debug")
|
|
||||||
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Also maintain system logging for compatibility
|
|
||||||
logger -t quecprofiles_daemon -p "daemon.$level" "$message"
|
logger -t quecprofiles_daemon -p "daemon.$level" "$message"
|
||||||
|
|
||||||
# Log to debug file (maintain existing behavior)
|
# Log to debug file
|
||||||
echo "[$timestamp] [$level] $message" >>"$DEBUG_LOG"
|
echo "[$timestamp] [$level] $message" >>"$DEBUG_LOG"
|
||||||
|
|
||||||
# For detailed logs or errors (maintain existing behavior)
|
# For detailed logs or errors
|
||||||
if [ "$level" = "error" ] || [ "$level" = "debug" ]; then
|
if [ "$level" = "error" ] || [ "$level" = "debug" ]; then
|
||||||
echo "[$timestamp] [$level] $message" >>"$DETAILED_LOG"
|
echo "[$timestamp] [$level] $message" >>"$DETAILED_LOG"
|
||||||
fi
|
fi
|
||||||
@@ -634,7 +607,6 @@ apply_profile_settings() {
|
|||||||
local current_nsa_nr5g_bands="${14}"
|
local current_nsa_nr5g_bands="${14}"
|
||||||
local current_imei="${15}"
|
local current_imei="${15}"
|
||||||
local iccid="${16}"
|
local iccid="${16}"
|
||||||
local mobile_provider="${17}"
|
|
||||||
|
|
||||||
# Set TTL to 0 (disabled) if not specified
|
# Set TTL to 0 (disabled) if not specified
|
||||||
ttl="${ttl:-0}"
|
ttl="${ttl:-0}"
|
||||||
@@ -647,7 +619,6 @@ apply_profile_settings() {
|
|||||||
log_message "- APN: $apn ($pdp_type)" "info"
|
log_message "- APN: $apn ($pdp_type)" "info"
|
||||||
log_message "- IMEI: $imei" "info"
|
log_message "- IMEI: $imei" "info"
|
||||||
log_message "- TTL: $ttl" "info"
|
log_message "- TTL: $ttl" "info"
|
||||||
log_message "- Mobile Provider: $mobile_provider" "info"
|
|
||||||
|
|
||||||
# Check if any changes are needed using improved comparison
|
# Check if any changes are needed using improved comparison
|
||||||
local needs_apn_change=0
|
local needs_apn_change=0
|
||||||
@@ -659,7 +630,6 @@ apply_profile_settings() {
|
|||||||
local needs_ttl_change=0
|
local needs_ttl_change=0
|
||||||
local changes_needed=0
|
local changes_needed=0
|
||||||
local requires_reboot=0
|
local requires_reboot=0
|
||||||
local change_for_reboot=""
|
|
||||||
|
|
||||||
# Use normalized comparison
|
# Use normalized comparison
|
||||||
compare_values "$current_apn" "$apn" "apn" && needs_apn_change=1 && changes_needed=1
|
compare_values "$current_apn" "$apn" "apn" && needs_apn_change=1 && changes_needed=1
|
||||||
@@ -834,7 +804,6 @@ apply_profile_settings() {
|
|||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
changes_made=1
|
changes_made=1
|
||||||
requires_reboot=1
|
requires_reboot=1
|
||||||
change_for_reboot="IMEI"
|
|
||||||
log_message "IMEI changed successfully to $imei (device will reboot)" "info"
|
log_message "IMEI changed successfully to $imei (device will reboot)" "info"
|
||||||
update_track "rebooting" "IMEI changed, device will reboot" "$profile_name" "95"
|
update_track "rebooting" "IMEI changed, device will reboot" "$profile_name" "95"
|
||||||
else
|
else
|
||||||
@@ -844,56 +813,9 @@ apply_profile_settings() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Apply unique rule setup for Verizon, but also handle "Other" Mobile Providers because of MPDN_rule shenanigans
|
|
||||||
# Probably requires reboot
|
|
||||||
output_check=$(execute_at_command "AT+QMAP=\"mpdn_rule\"")
|
|
||||||
sleep 1 # Short delay to ensure command is processed
|
|
||||||
qmap_rule0=$(echo "$output_check" | grep '+QMAP: "MPDN_rule",0,')
|
|
||||||
qmap_ippt_rule0=$(echo "$qmap_rule0" | cut -d',' -f5)
|
|
||||||
if [ $apply_success -eq 1 ] && [ -n "$mobile_provider" ]; then
|
|
||||||
if [ "$mobile_provider" = "Verizon" ]; then
|
|
||||||
# If Verizon, data call should be set to rule 3, AT+QMAP="mpdn_rule",0,3,0,0,1
|
|
||||||
if echo "$qmap_rule0" | awk -F',' '{exit !($2==0 && $3==3 && $6==1)}'; then
|
|
||||||
log_message "Verizon rule already set correctly, no changes needed" "info"
|
|
||||||
else
|
|
||||||
log_message "Setting Verizon data call mpdn_rule to 3" "info"
|
|
||||||
update_track "applying" "Setting Verizon data call rule to 3" "$profile_name" "100"
|
|
||||||
verizon_cmd="AT+QMAP=\"mpdn_rule\",0,3,0,$qmap_ippt_rule0,1"
|
|
||||||
execute_at_command "$verizon_cmd" 10 "$token_id" >/dev/null
|
|
||||||
sleep 1 # Short delay to ensure command is processed
|
|
||||||
fi
|
|
||||||
elif [ "$mobile_provider" = "Other" ]; then
|
|
||||||
# Check if MPDN_rule 0 is already set to all zeros
|
|
||||||
if echo "$qmap_rule0" | awk -F',' '{exit !($2==0 && $3==0 && $6==0)}'; then
|
|
||||||
log_message "Default rule already set correctly, no changes needed" "info"
|
|
||||||
else
|
|
||||||
log_message "Setting to default mpdn_rule and releasing" "info"
|
|
||||||
update_track "applying" "Setting Default data call mpdn_rule to 0" "$profile_name" "100"
|
|
||||||
def_cmd1="AT+QMAP=\"mpdn_rule\",0"
|
|
||||||
execute_at_command "$def_cmd1" 10 "$token_id"
|
|
||||||
sleep 1 # Short delay to ensure command is processed
|
|
||||||
def_cmd2="AT+QMAP=\"mpdn_rule\",0,1,0,$qmap_ippt_rule0,1"
|
|
||||||
execute_at_command "$def_cmd2" 10 "$token_id"
|
|
||||||
sleep 1 # Short delay to ensure command is processed
|
|
||||||
if [ "$qmap_ippt_rule0" = "0" ]; then
|
|
||||||
log_message "IPPT is disabled for rule, release the MPDN_rule" "info"
|
|
||||||
def_cmd3="AT+QMAP=\"mpdn_rule\",0"
|
|
||||||
execute_at_command "$def_cmd3" 10 "$token_id"
|
|
||||||
sleep 1 # Short delay to ensure command is processed
|
|
||||||
if [ "$(cat /sys/devices/soc0/machine)" = "SDXPINN" ]; then
|
|
||||||
requires_reboot=1
|
|
||||||
change_for_reboot="MPDN_rule"
|
|
||||||
update_track "rebooting" "MPDN_rule released, device will reboot" "$profile_name" "105"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_message "IPPT is enabled for rule0 not releasing MPDN_rule, no reboot needed: IPPT Value $qmap_ippt_rule0" "info"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Release token
|
# Release token
|
||||||
release_token "$token_id"
|
release_token "$token_id"
|
||||||
|
|
||||||
# Mark profile as applied if changes were made
|
# Mark profile as applied if changes were made
|
||||||
if [ $changes_made -eq 1 ]; then
|
if [ $changes_made -eq 1 ]; then
|
||||||
mark_profile_applied "$iccid" "$profile_name"
|
mark_profile_applied "$iccid" "$profile_name"
|
||||||
@@ -902,7 +824,7 @@ apply_profile_settings() {
|
|||||||
# If IMEI was changed, need to reboot
|
# If IMEI was changed, need to reboot
|
||||||
if [ $requires_reboot -eq 1 ]; then
|
if [ $requires_reboot -eq 1 ]; then
|
||||||
log_message "IMEI change requires reboot, scheduling reboot..." "info"
|
log_message "IMEI change requires reboot, scheduling reboot..." "info"
|
||||||
update_track "rebooting" "Device is rebooting to apply $change_for_reboot change" "$profile_name" "100"
|
update_track "rebooting" "Device is rebooting to apply IMEI change" "$profile_name" "100"
|
||||||
sleep 2
|
sleep 2
|
||||||
reboot &
|
reboot &
|
||||||
return 0
|
return 0
|
||||||
@@ -991,12 +913,11 @@ check_profile() {
|
|||||||
local pdp_type=$(uci -q get quecprofiles.$profile_index.pdp_type)
|
local pdp_type=$(uci -q get quecprofiles.$profile_index.pdp_type)
|
||||||
local imei=$(uci -q get quecprofiles.$profile_index.imei)
|
local imei=$(uci -q get quecprofiles.$profile_index.imei)
|
||||||
local ttl=$(uci -q get quecprofiles.$profile_index.ttl)
|
local ttl=$(uci -q get quecprofiles.$profile_index.ttl)
|
||||||
local mobile_provider=$(uci -q get quecprofiles.$profile_index.mobile_provider)
|
|
||||||
|
|
||||||
# Check if profile is paused
|
# Check if profile is paused
|
||||||
local paused=$(uci -q get quecprofiles.$profile_index.paused)
|
local paused=$(uci -q get quecprofiles.$profile_index.paused)
|
||||||
paused="${paused:-0}" # Default to not paused if not set
|
paused="${paused:-0}" # Default to not paused if not set
|
||||||
|
|
||||||
# Skip applying paused profiles
|
# Skip applying paused profiles
|
||||||
if [ "$paused" = "1" ]; then
|
if [ "$paused" = "1" ]; then
|
||||||
log_message "Profile '$profile_name' is paused, skipping application" "info"
|
log_message "Profile '$profile_name' is paused, skipping application" "info"
|
||||||
@@ -1061,7 +982,7 @@ check_profile() {
|
|||||||
# Apply profile settings with the new parameters
|
# Apply profile settings with the new parameters
|
||||||
apply_profile_settings "$profile_name" "$network_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" \
|
apply_profile_settings "$profile_name" "$network_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" \
|
||||||
"$apn" "$pdp_type" "$imei" "$ttl" "$current_apn" "$current_mode" "$current_lte_bands" \
|
"$apn" "$pdp_type" "$imei" "$ttl" "$current_apn" "$current_mode" "$current_lte_bands" \
|
||||||
"$current_sa_nr5g_bands" "$current_nsa_nr5g_bands" "$current_imei" "$current_iccid" "$mobile_provider"
|
"$current_sa_nr5g_bands" "$current_nsa_nr5g_bands" "$current_imei" "$current_iccid"
|
||||||
return $?
|
return $?
|
||||||
else
|
else
|
||||||
log_message "Automatic profile switching is disabled, not applying profile" "info"
|
log_message "Automatic profile switching is disabled, not applying profile" "info"
|
||||||
@@ -1117,7 +1038,7 @@ main() {
|
|||||||
while [ $sleep_counter -lt $check_interval ]; do
|
while [ $sleep_counter -lt $check_interval ]; do
|
||||||
sleep 5
|
sleep 5
|
||||||
sleep_counter=$((sleep_counter + 5))
|
sleep_counter=$((sleep_counter + 5))
|
||||||
|
|
||||||
# Check for manual trigger during sleep
|
# Check for manual trigger during sleep
|
||||||
if [ -f "$CHECK_TRIGGER" ]; then
|
if [ -f "$CHECK_TRIGGER" ]; then
|
||||||
log_message "Manual check triggered during sleep" "info"
|
log_message "Manual check triggered during sleep" "info"
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
# QuecWatch Daemon
|
# QuecWatch Daemon
|
||||||
# Monitors cellular connectivity and performs recovery actions
|
# Monitors cellular connectivity and performs recovery actions
|
||||||
|
|
||||||
# Load centralized logging
|
|
||||||
. /www/cgi-bin/services/quecmanager_logger.sh
|
|
||||||
|
|
||||||
# Load UCI configuration functions
|
# Load UCI configuration functions
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
|
|
||||||
@@ -20,7 +17,6 @@ RETRY_COUNT_FILE="/tmp/quecwatch_retry_count"
|
|||||||
UCI_CONFIG="quecmanager"
|
UCI_CONFIG="quecmanager"
|
||||||
MAX_TOKEN_WAIT=10 # Maximum seconds to wait for token acquisition
|
MAX_TOKEN_WAIT=10 # Maximum seconds to wait for token acquisition
|
||||||
TOKEN_PRIORITY=15 # Medium priority (between profiles and metrics)
|
TOKEN_PRIORITY=15 # Medium priority (between profiles and metrics)
|
||||||
SCRIPT_NAME_LOG="quecwatch"
|
|
||||||
|
|
||||||
# Ensure directories exist
|
# Ensure directories exist
|
||||||
mkdir -p "$LOG_DIR" "$QUEUE_DIR"
|
mkdir -p "$LOG_DIR" "$QUEUE_DIR"
|
||||||
@@ -29,33 +25,17 @@ mkdir -p "$LOG_DIR" "$QUEUE_DIR"
|
|||||||
echo "$$" > "$PID_FILE"
|
echo "$$" > "$PID_FILE"
|
||||||
chmod 644 "$PID_FILE"
|
chmod 644 "$PID_FILE"
|
||||||
|
|
||||||
# Function to log messages - now uses centralized logging
|
# Function to log messages
|
||||||
log_message() {
|
log_message() {
|
||||||
local level="${2:-info}"
|
local level="${2:-info}"
|
||||||
local message="$1"
|
local message="$1"
|
||||||
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
|
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
# Use centralized logging
|
# Log to file
|
||||||
case "$level" in
|
|
||||||
"error")
|
|
||||||
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"warn")
|
|
||||||
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
"debug")
|
|
||||||
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Also maintain system logging for compatibility
|
|
||||||
logger -t quecwatch -p "daemon.$level" "$message"
|
|
||||||
|
|
||||||
# Log to file (maintain existing behavior)
|
|
||||||
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
|
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Log to system log
|
||||||
|
logger -t quecwatch -p "daemon.$level" "$message"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to update status
|
# Function to update status
|
||||||
|
|||||||
Reference in New Issue
Block a user