Initial parts of the OpenWRT subsystem skeleton
This commit is contained in:
945
old/RMxxx_rgmii_toolkit.sh
Normal file
945
old/RMxxx_rgmii_toolkit.sh
Normal file
@@ -0,0 +1,945 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Define toolkit paths
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
TMP_DIR="/tmp"
|
||||
USRDATA_DIR="/usrdata"
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
TAILSCALE_DIR="/usrdata/tailscale"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
# AT Command Script Variables and Functions
|
||||
DEVICE_FILE="/dev/smd7"
|
||||
TIMEOUT=4 # Set a timeout for the response
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Basic AT commands without socat bridge for fast responce commands only
|
||||
start_listening() {
|
||||
cat "$DEVICE_FILE" > /tmp/device_readout &
|
||||
CAT_PID=$!
|
||||
}
|
||||
|
||||
send_at_command() {
|
||||
echo -e "\e[1;31mThis only works for basic quick responding commands!\e[0m" # Red
|
||||
echo -e "\e[1;36mType 'install' to simply type atcmd in shell from now on\e[0m"
|
||||
echo -e "\e[1;36mThe installed version is much better than this portable version\e[0m"
|
||||
echo -e "\e[1;32mEnter AT command (or type 'exit' to quit): \e[0m"
|
||||
read at_command
|
||||
if [ "$at_command" = "exit" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$at_command" = "install" ]; then
|
||||
install_update_at_socat
|
||||
echo -e "\e[1;32mInstalled. Type atcmd from adb shell or ssh to start an AT Command session\e[0m"
|
||||
return 1
|
||||
fi
|
||||
echo -e "${at_command}\r" > "$DEVICE_FILE"
|
||||
}
|
||||
|
||||
wait_for_response() {
|
||||
local start_time=$(date +%s)
|
||||
local current_time
|
||||
local elapsed_time
|
||||
|
||||
echo -e "\e[1;32mCommand sent, waiting for response...\e[0m"
|
||||
while true; do
|
||||
if grep -qe "OK" -e "ERROR" /tmp/device_readout; then
|
||||
echo -e "\e[1;32mResponse received:\e[0m"
|
||||
cat /tmp/device_readout
|
||||
return 0
|
||||
fi
|
||||
current_time=$(date +%s)
|
||||
elapsed_time=$((current_time - start_time))
|
||||
if [ "$elapsed_time" -ge "$TIMEOUT" ]; then
|
||||
echo -e "\e[1;31mError: Response timed out.\e[0m" # Red
|
||||
echo -e "\e[1;32mIf the responce takes longer than a second or 2 to respond this will not work\e[0m" # Green
|
||||
echo -e "\e[1;36mType install to install the better version of this that will work.\e[0m" # Cyan
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
kill "$CAT_PID"
|
||||
wait "$CAT_PID" 2>/dev/null
|
||||
rm -f /tmp/device_readout
|
||||
}
|
||||
|
||||
send_at_commands() {
|
||||
if [ -c "$DEVICE_FILE" ]; then
|
||||
while true; do
|
||||
start_listening
|
||||
send_at_command
|
||||
if [ $? -eq 1 ]; then
|
||||
cleanup
|
||||
break
|
||||
fi
|
||||
wait_for_response
|
||||
cleanup
|
||||
done
|
||||
else
|
||||
echo -e "\e[1;31mError: Device $DEVICE_FILE does not exist!\e[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for existing Entware/opkg installation, install if not installed
|
||||
ensure_entware_installed() {
|
||||
remount_rw
|
||||
if [ ! -f "/opt/bin/opkg" ]; then
|
||||
echo -e "\e[1;32mInstalling Entware/OPKG\e[0m"
|
||||
cd /tmp && wget -O installentware.sh "$GITROOT/installentware.sh" && chmod +x installentware.sh && ./installentware.sh
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mEntware/OPKG installation failed. Please check your internet connection or the repository URL.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
cd /
|
||||
else
|
||||
echo -e "\e[1;32mEntware/OPKG is already installed.\e[0m"
|
||||
if [ "$(readlink /bin/login)" != "/opt/bin/login" ]; then
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
|
||||
# Install basic and useful utilities
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
fi
|
||||
|
||||
if [ ! -f "/usrdata/root/.profile" ]; then
|
||||
opkg update && opkg install shadow-useradd
|
||||
mkdir -p /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
fi
|
||||
fi
|
||||
if [ ! -f "/opt/sbin/useradd" ]; then
|
||||
echo "useradd does not exist. Installing shadow-useradd..."
|
||||
opkg install shadow-useradd
|
||||
else
|
||||
echo "useradd already exists. Continuing..."
|
||||
fi
|
||||
|
||||
if [ ! -f "/usr/bin/curl" ] && [ ! -f "/opt/bin/curl" ]; then
|
||||
echo "curl does not exist. Installing curl..."
|
||||
opkg update && opkg install curl
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mFailed to install curl. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "curl already exists. Continuing..."
|
||||
fi
|
||||
}
|
||||
|
||||
#Uninstall Entware if the Users chooses
|
||||
uninstall_entware() {
|
||||
echo -e '\033[31mInfo: Starting Entware/OPKG uninstallation...\033[0m'
|
||||
|
||||
# Stop services
|
||||
systemctl stop rc.unslung.service
|
||||
/opt/etc/init.d/rc.unslung stop
|
||||
rm /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||
rm /lib/systemd/system/rc.unslung.service
|
||||
|
||||
systemctl stop opt.mount
|
||||
rm /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||
rm /lib/systemd/system/opt.mount
|
||||
rm /lib/systemd/system/start-opt-mount.service
|
||||
|
||||
# Unmount /opt if mounted
|
||||
mountpoint -q /opt && umount /opt
|
||||
|
||||
# Remove Entware installation directory
|
||||
rm -rf /usrdata/opt
|
||||
rm -rf /opt
|
||||
|
||||
# Reload systemctl daemon
|
||||
systemctl daemon-reload
|
||||
|
||||
# Optionally, clean up any modifications to /etc/profile or other system files
|
||||
# Restore original link to login binary compiled by Quectel
|
||||
rm /bin/login
|
||||
ln /bin/login.shadow /bin/login
|
||||
|
||||
echo -e '\033[32mInfo: Entware/OPKG has been uninstalled successfully.\033[0m'
|
||||
}
|
||||
|
||||
# function to configure the fetures of simplefirewall
|
||||
configure_simple_firewall() {
|
||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||
echo -e "\033[0;31mSimplefirewall is not installed, would you like to install it?\033[0m"
|
||||
echo -e "\033[0;32m1) Yes\033[0m"
|
||||
echo -e "\033[0;31m2) No\033[0m"
|
||||
read -p "Enter your choice (1-2): " install_choice
|
||||
|
||||
case $install_choice in
|
||||
1)
|
||||
install_simple_firewall
|
||||
;;
|
||||
2)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
echo -e "\033[0;31mInvalid choice. Please select either 1 or 2.\033[0m"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo -e "\e[1;32mConfigure Simple Firewall:\e[0m"
|
||||
echo -e "\e[38;5;208m1) Configure incoming port block\e[0m"
|
||||
echo -e "\e[38;5;27m2) Configure TTL\e[0m"
|
||||
read -p "Enter your choice (1-2): " menu_choice
|
||||
|
||||
case $menu_choice in
|
||||
1)
|
||||
# Original ports configuration code with exit option
|
||||
current_ports_line=$(grep '^PORTS=' "$SIMPLE_FIREWALL_SCRIPT")
|
||||
ports=$(echo "$current_ports_line" | cut -d'=' -f2 | tr -d '()' | tr ' ' '\n' | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mCurrent configured ports:\e[0m"
|
||||
echo "$ports" | awk '{print NR") "$0}'
|
||||
|
||||
while true; do
|
||||
echo -e "\e[1;32mEnter a port number to add/remove, or type 'done' or 'exit' to finish:\e[0m"
|
||||
read port
|
||||
if [ "$port" = "done" ] || [ "$port" = "exit" ]; then
|
||||
if [ "$port" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting without making changes...\e[0m"
|
||||
return
|
||||
fi
|
||||
break
|
||||
elif ! echo "$port" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
elif echo "$ports" | grep -q "^$port\$"; then
|
||||
ports=$(echo "$ports" | grep -v "^$port\$")
|
||||
echo -e "\e[1;32mPort $port removed.\e[0m"
|
||||
else
|
||||
ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mPort $port added.\e[0m"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$port" != "exit" ]; then
|
||||
new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))"
|
||||
sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
# TTL configuration code
|
||||
ttl_value=$(cat /usrdata/simplefirewall/ttlvalue)
|
||||
if [ "$ttl_value" -eq 0 ]; then
|
||||
echo -e "\e[1;31mTTL is not set.\e[0m"
|
||||
else
|
||||
echo -e "\e[1;32mTTL value is set to $ttl_value.\e[0m"
|
||||
fi
|
||||
|
||||
echo -e "\e[1;31mType 'exit' to cancel.\e[0m"
|
||||
read -p "What do you want the TTL value to be: " new_ttl_value
|
||||
if [ "$new_ttl_value" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting TTL configuration...\e[0m"
|
||||
return
|
||||
elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
return
|
||||
else
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
echo -e "\033[0;32mTTL value updated to $new_ttl_value.\033[0m"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Please select either 1 or 2.\e[0m"
|
||||
;;
|
||||
esac
|
||||
|
||||
systemctl restart simplefirewall
|
||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||
}
|
||||
|
||||
set_simpleadmin_passwd(){
|
||||
ensure_entware_installed
|
||||
opkg update
|
||||
opkg install libaprutil
|
||||
wget -O /usrdata/root/bin/htpasswd $GITROOT/simpleadmin/htpasswd && chmod +x /usrdata/root/bin/htpasswd
|
||||
wget -O /usrdata/root/bin/simplepasswd $GITROOT/simpleadmin/simplepasswd && chmod +x /usrdata/root/bin/simplepasswd
|
||||
echo -e "\e[1;32mTo change your simpleadmin (admin) password in the future...\e[0m"
|
||||
echo -e "\e[1;32mIn the console type simplepasswd and press enter\e[0m"
|
||||
/usrdata/root/bin/simplepasswd
|
||||
|
||||
}
|
||||
|
||||
set_root_passwd() {
|
||||
echo -e "\e[1;31mPlease set the root/console password.\e[0m"
|
||||
/opt/bin/passwd
|
||||
}
|
||||
|
||||
# Function to install/update Simple Admin
|
||||
install_simple_admin() {
|
||||
echo -e "\e[1;32mInstalling Simpleadmin 2.0\e[0m"
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;31m2) Installing Simpleadmin 2.0\e[0m"
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh $GITROOT/simpleupdates/scripts/update_socat-at-bridge.sh && chmod +x /usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: socat-at-bridge\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_socat-at-bridge.sh
|
||||
echo -e "\e[1;32m Dependency: socat-at-bridge has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simplefirewall.sh $GITROOT/simpleupdates/scripts/update_simplefirewall.sh && chmod +x /usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32mInstalling/updating dependency: simplefirewall\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simplefirewall.sh
|
||||
echo -e "\e[1;32m Dependency: simplefirewall has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
set_simpleadmin_passwd
|
||||
wget -O /usrdata/simpleupdates/scripts/update_simpleadmin.sh $GITROOT/simpleupdates/scripts/update_simpleadmin.sh && chmod +x /usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Simpleadmin content\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_simpleadmin.sh
|
||||
echo -e "\e[1;32mSimpleadmin content has been updated/installed.\e[0m"
|
||||
sleep 1
|
||||
break
|
||||
}
|
||||
|
||||
# Function to Uninstall Simpleadmin and dependencies
|
||||
uninstall_simpleadmin_components() {
|
||||
echo -e "\e[1;32mStarting the uninstallation process for Simpleadmin components.\e[0m"
|
||||
echo -e "\e[1;32mNote: Uninstalling certain components may affect the functionality of others.\e[0m"
|
||||
remount_rw
|
||||
|
||||
# Uninstall Simple Firewall
|
||||
echo -e "\e[1;32mDo you want to uninstall Simplefirewall?\e[0m"
|
||||
echo -e "\e[1;31mIf you do, the TTL part of simpleadmin will no longer work.\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_simplefirewall
|
||||
if [ "$choice_simplefirewall" -eq 1 ]; then
|
||||
echo "Uninstalling Simplefirewall..."
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
rm -f /lib/systemd/system/simplefirewall.service
|
||||
rm -f /lib/systemd/system/ttl-override.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_FIREWALL_DIR"
|
||||
echo "Simplefirewall uninstalled."
|
||||
fi
|
||||
|
||||
# Uninstall socat-at-bridge
|
||||
echo -e "\e[1;32mDo you want to uninstall socat-at-bridge?\e[0m"
|
||||
echo -e "\e[1;31mIf you do, AT commands and the stat page will no longer work. atcmd won't either.\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_socat_at_bridge
|
||||
if [ "$choice_socat_at_bridge" -eq 1 ]; then
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/micropython" > /dev/null 2>&1
|
||||
rm -rf "/usrdata/at-telnet" > /dev/null 2>&1
|
||||
echo -e "\033[0;32mAT Socat Bridge services removed!...\033[0m"
|
||||
fi
|
||||
|
||||
# Uninstall ttyd
|
||||
echo -e "\e[1;32mDo you want to uninstall ttyd (simpleadmin console)?\e[0m"
|
||||
echo -e "\e[1;31mWarning: Do not uninstall if you are currently using ttyd to do this!!!\e[0m"
|
||||
echo -e "\e[1;32m1) Yes\e[0m"
|
||||
echo -e "\e[1;31m2) No\e[0m"
|
||||
read -p "Enter your choice (1 or 2): " choice_simpleadmin
|
||||
if [ "$choice_simpleadmin" -eq 1 ]; then
|
||||
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||
systemctl stop ttyd
|
||||
rm -rf /usrdata/ttyd
|
||||
rm /lib/systemd/system/ttyd.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||
rm /bin/ttyd
|
||||
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||
fi
|
||||
|
||||
echo "Uninstalling the rest of Simpleadmin..."
|
||||
|
||||
# Check if Lighttpd service is installed and remove it if present
|
||||
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||
echo "Lighttpd detected, uninstalling Lighttpd and its modules..."
|
||||
systemctl stop lighttpd
|
||||
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||
rm -rf $LIGHTTPD_DIR
|
||||
fi
|
||||
|
||||
systemctl stop simpleadmin_generate_status
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
echo "The rest of Simpleadmin and Lighttpd (if present) uninstalled."
|
||||
remount_ro
|
||||
|
||||
echo "Uninstallation process completed."
|
||||
}
|
||||
|
||||
# Function for Tailscale Submenu
|
||||
tailscale_menu() {
|
||||
while true; do
|
||||
echo -e "\e[1;32mTailscale Menu\e[0m"
|
||||
echo -e "\e[1;32m1) Install/Update Tailscale\e[0m"
|
||||
echo -e "\e[1;36m2) Configure Tailscale\e[0m"
|
||||
echo -e "\e[1;31m3) Return to Main Menu\e[0m"
|
||||
read -p "Enter your choice: " tailscale_choice
|
||||
|
||||
case $tailscale_choice in
|
||||
1) install_update_tailscale;;
|
||||
2) configure_tailscale;;
|
||||
3) break;;
|
||||
*) echo "Invalid option";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Function to install, update, or remove Tailscale
|
||||
install_update_tailscale() {
|
||||
echo -e "\e[1;31m2) Installing tailscale from the $GITTREE branch\e[0m"
|
||||
ensure_entware_installed
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_tailscale.sh $GITROOT/simpleupdates/scripts/update_tailscale.sh && chmod +x /usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32mInstalling/updating: Tailscale\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
remount_rw
|
||||
/usrdata/simpleupdates/scripts/update_tailscale.sh
|
||||
echo -e "\e[1;32m Tailscale has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
# Function to Configure Tailscale
|
||||
configure_tailscale() {
|
||||
while true; do
|
||||
echo "Configure Tailscale"
|
||||
echo -e "\e[38;5;40m1) Enable Tailscale Web UI at http://192.168.225.1:8088 (Gateway on port 8088)\e[0m" # Green
|
||||
echo -e "\e[38;5;196m2) Disable Tailscale Web UI\e[0m" # Red
|
||||
echo -e "\e[38;5;27m3) Connect to Tailnet\e[0m" # Brown
|
||||
echo -e "\e[38;5;87m4) Connect to Tailnet with SSH ON\e[0m" # Light cyan
|
||||
echo -e "\e[38;5;105m5) Reconnect to Tailnet with SSH OFF\e[0m" # Light magenta
|
||||
echo -e "\e[38;5;172m6) Disconnect from Tailnet (reconnects at reboot)\e[0m" # Light yellow
|
||||
echo -e "\e[1;31m7) Logout from tailscale account\e[0m"
|
||||
echo -e "\e[38;5;27m8) Return to Tailscale Menu\e[0m"
|
||||
read -p "Enter your choice: " config_choice
|
||||
|
||||
case $config_choice in
|
||||
1)
|
||||
remount_rw
|
||||
cd /lib/systemd/system/
|
||||
wget -O tailscale-webui.service $GITROOT/tailscale/systemd/tailscale-webui.service
|
||||
wget -O tailscale-webui-trigger.service $GITROOT/tailscale/systemd/tailscale-webui-trigger.service
|
||||
ln -sf /lib/systemd/system/tailscale-webui-trigger.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Tailscale Web UI Enabled"
|
||||
echo "Starting Web UI..."
|
||||
systemctl start tailscale-webui
|
||||
echo "Web UI started!"
|
||||
remount_ro
|
||||
;;
|
||||
2)
|
||||
remount_rw
|
||||
systemctl stop tailscale-webui
|
||||
systemctl disable tailscale-webui-trigger
|
||||
rm /lib/systemd/system/multi-user.target.wants/tailscale-webui.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/tailscale-webui-trigger.service
|
||||
rm /lib/systemd/system/tailscale-webui.service
|
||||
rm /lib/systemd/system/tailscale-webui-trigger.service
|
||||
systemctl daemon-reload
|
||||
echo "Tailscale Web UI Stopped and Disabled"
|
||||
remount_ro
|
||||
;;
|
||||
3) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
4) $TAILSCALE_DIR/tailscale up --ssh --accept-dns=false --reset;;
|
||||
5) $TAILSCALE_DIR/tailscale up --accept-dns=false --reset;;
|
||||
6) $TAILSCALE_DIR/tailscale down;;
|
||||
7) $TAILSCALE_DIR/tailscale logout;;
|
||||
8) break;;
|
||||
*) echo "Invalid option";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Function to manage Daily Reboot Timer
|
||||
manage_reboot_timer() {
|
||||
# Remount root filesystem as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
# Check if the rebootmodem service, timer, or trigger already exists
|
||||
if [ -f /lib/systemd/system/rebootmodem.service ] || [ -f /lib/systemd/system/rebootmodem.timer ] || [ -f /lib/systemd/system/rebootmodem-trigger.service ]; then
|
||||
echo -e "\e[1;32mThe rebootmodem service/timer/trigger is already installed.\e[0m"
|
||||
echo -e "\e[1;32m1) Change\e[0m" # Green
|
||||
echo -e "\e[1;31m2) Remove\e[0m" # Red
|
||||
read -p "Enter your choice (1 for Change, 2 for Remove): " reboot_choice
|
||||
|
||||
case $reboot_choice in
|
||||
2)
|
||||
# Stop and disable timer and trigger service by removing symlinks
|
||||
systemctl stop rebootmodem.timer
|
||||
systemctl stop rebootmodem-trigger.service
|
||||
|
||||
# Remove symbolic links and files
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/rebootmodem-trigger.service
|
||||
rm -f /lib/systemd/system/rebootmodem.service
|
||||
rm -f /lib/systemd/system/rebootmodem.timer
|
||||
rm -f /lib/systemd/system/rebootmodem-trigger.service
|
||||
rm -f "$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Reload systemd to apply changes
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "\e[1;32mRebootmodem service, timer, trigger, and script removed successfully.\e[0m"
|
||||
;;
|
||||
1)
|
||||
printf "Enter the new time for daily reboot (24-hour format in Coordinated Universal Time, HH:MM): "
|
||||
read new_time
|
||||
|
||||
# Validate the new time format using grep
|
||||
if ! echo "$new_time" | grep -qE '^([01]?[0-9]|2[0-3]):[0-5][0-9]$'; then
|
||||
echo "Invalid time format. Exiting."
|
||||
exit 1
|
||||
else
|
||||
# Remove old symlinks and script
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/rebootmodem-trigger.service
|
||||
rm -f "$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Set the user time to the new time and recreate the service, timer, trigger, and script
|
||||
user_time=$new_time
|
||||
create_service_and_timer
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Exiting.\e[0m"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
printf "Enter the time for daily reboot (24-hour format in UTC, HH:MM): "
|
||||
read user_time
|
||||
|
||||
# Validate the time format using grep
|
||||
if ! echo "$user_time" | grep -qE '^([01]?[0-9]|2[0-3]):[0-5][0-9]$'; then
|
||||
echo "Invalid time format. Exiting."
|
||||
exit 1
|
||||
else
|
||||
create_service_and_timer
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remount root filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Function to create systemd service and timer files with the user-specified time for the reboot timer
|
||||
create_service_and_timer() {
|
||||
remount_rw
|
||||
# Define the path for the modem reboot script
|
||||
MODEM_REBOOT_SCRIPT="$USRDATA_DIR/reboot_modem.sh"
|
||||
|
||||
# Create the modem reboot script
|
||||
echo "#!/bin/sh
|
||||
/bin/echo -e 'AT+CFUN=1,1 \r' > /dev/smd7" > "$MODEM_REBOOT_SCRIPT"
|
||||
|
||||
# Make the script executable
|
||||
chmod +x "$MODEM_REBOOT_SCRIPT"
|
||||
|
||||
# Create the systemd service file for reboot
|
||||
echo "[Unit]
|
||||
Description=Reboot Modem Daily
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh /usrdata/reboot_modem.sh
|
||||
Restart=no
|
||||
RemainAfterExit=no" > /lib/systemd/system/rebootmodem.service
|
||||
|
||||
# Create the systemd timer file with the user-specified time
|
||||
echo "[Unit]
|
||||
Description=Starts rebootmodem.service daily at the specified time
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* $user_time:00
|
||||
Persistent=false" > /lib/systemd/system/rebootmodem.timer
|
||||
|
||||
# Create a trigger service that starts the timer at boot
|
||||
echo "[Unit]
|
||||
Description=Trigger the rebootmodem timer at boot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start rebootmodem.timer
|
||||
RemainAfterExit=yes" > /lib/systemd/system/rebootmodem-trigger.service
|
||||
|
||||
# Create symbolic links for the trigger service in the wanted directory
|
||||
ln -sf /lib/systemd/system/rebootmodem-trigger.service /lib/systemd/system/multi-user.target.wants/
|
||||
|
||||
# Reload systemd to recognize the new timer and trigger service
|
||||
systemctl daemon-reload
|
||||
sleep 2s
|
||||
|
||||
# Start the trigger service, which will start the timer
|
||||
systemctl start rebootmodem-trigger.service
|
||||
remount_ro
|
||||
|
||||
# Confirmation
|
||||
echo -e "\e[1;32mRebootmodem-trigger service created and started successfully.\e[0m"
|
||||
echo -e "\e[1;32mReboot schedule set successfully. The modem will reboot daily at $user_time UTC.\e[0m"
|
||||
}
|
||||
|
||||
manage_cfun_fix() {
|
||||
cfun_service_path="/lib/systemd/system/cfunfix.service"
|
||||
cfun_fix_script="/usrdata/cfun_fix.sh"
|
||||
|
||||
mount -o remount,rw /
|
||||
|
||||
if [ -f "$cfun_service_path" ]; then
|
||||
echo -e "\e[1;32mThe CFUN fix is already installed. Do you want to remove it?\e[0m" # Green
|
||||
echo -e "\e[1;32m1) Yes\e[0m" # Green
|
||||
echo -e "\e[1;31m2) No\e[0m" # Red
|
||||
read -p "Enter your choice: " choice
|
||||
|
||||
if [ "$choice" = "1" ]; then
|
||||
echo "Removing CFUN fix..."
|
||||
systemctl stop cfunfix.service
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/cfunfix.service
|
||||
rm -f "$cfun_service_path"
|
||||
rm -f "$cfun_fix_script"
|
||||
systemctl daemon-reload
|
||||
echo "CFUN fix has been removed."
|
||||
else
|
||||
echo "Returning to main menu..."
|
||||
fi
|
||||
else
|
||||
echo -e "\e[1;32mInstalling CFUN fix...\e[0m"
|
||||
|
||||
# Create the CFUN fix script
|
||||
echo "#!/bin/sh
|
||||
/bin/echo -e 'AT+CFUN=1 \r' > /dev/smd7" > "$cfun_fix_script"
|
||||
chmod +x "$cfun_fix_script"
|
||||
|
||||
# Create the systemd service file to execute the CFUN fix script at boot
|
||||
echo "[Unit]
|
||||
Description=CFUN Fix Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=$cfun_fix_script
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target" > "$cfun_service_path"
|
||||
|
||||
ln -sf "$cfun_service_path" "/lib/systemd/system/multi-user.target.wants/"
|
||||
systemctl daemon-reload
|
||||
mount -o remount,ro /
|
||||
echo -e "\e[1;32mCFUN fix has been installed and will execute at every boot.\e[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
install_sshd() {
|
||||
if [ -d "/usrdata/sshd" ]; then
|
||||
echo -e "\e[1;31mSSHD is currently installed.\e[0m"
|
||||
echo -e "Do you want to update or uninstall?"
|
||||
echo -e "1.) Update"
|
||||
echo -e "2.) Uninstall"
|
||||
read -p "Select an option (1 or 2): " sshd_choice
|
||||
|
||||
case $sshd_choice in
|
||||
1)
|
||||
echo -e "\e[1;31m2) Installing sshd from the $GITTREE branch\e[0m"
|
||||
;;
|
||||
2)
|
||||
echo -e "\e[1;31mUninstalling SSHD...\e[0m"
|
||||
systemctl stop sshd
|
||||
rm /lib/systemd/system/sshd.service
|
||||
opkg remove openssh-server-pam
|
||||
echo -e "\e[1;32mSSHD has been uninstalled successfully.\e[0m"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option. Please select 1 or 2.\e[0m"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Proceed with installation or updating if not uninstalling
|
||||
ensure_entware_installed
|
||||
mkdir /usrdata/simpleupdates > /dev/null 2>&1
|
||||
mkdir /usrdata/simpleupdates/scripts > /dev/null 2>&1
|
||||
wget -O /usrdata/simpleupdates/scripts/update_sshd.sh $GITROOT/simpleupdates/scripts/update_sshd.sh && chmod +x /usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32mInstalling/updating: SSHd\e[0m"
|
||||
echo -e "\e[1;32mPlease Wait....\e[0m"
|
||||
/usrdata/simpleupdates/scripts/update_sshd.sh
|
||||
echo -e "\e[1;32m SSHd has been updated/installed.\e[0m"
|
||||
}
|
||||
|
||||
|
||||
# Main menu
|
||||
|
||||
ARCH=$(uname -a)
|
||||
if echo "$ARCH" | grep -q "aarch64"; then
|
||||
cd /tmp && wget -O RM55x_rcPCIe_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXPINN/RM55x_rcPCIe_toolkit.sh && chmod +x RM55x_rcPCIe_toolkit.sh && ./RM55x_rcPCIe_toolkit.sh && cd /
|
||||
exit 0
|
||||
elif echo "$ARCH" | grep -q "armv7l"; then
|
||||
# Continue if architecture is armv7l
|
||||
echo "Architecture is armv7l, continuing..."
|
||||
else
|
||||
uname -a
|
||||
echo "Unsupported architecture."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while true; do
|
||||
echo " .%+: "
|
||||
echo " .*@@@-. "
|
||||
echo " :@@@@- "
|
||||
echo " @@@@#. "
|
||||
echo " -@@@@#. "
|
||||
echo " :. %@@@@: -# "
|
||||
echo " .+- #@@@@%.+@- "
|
||||
echo " .#- . +@@@@# #@- "
|
||||
echo " -@*@*@% @@@@@::@@= "
|
||||
echo ".+%@@@@@@@@@%=. =@@@@# #@@- .. "
|
||||
echo " .@@@@@: :@@@@@ =@@@..%= "
|
||||
echo " -::@-.+. @@@@@.=@@@- =@- "
|
||||
echo " .@- .@@@@@:.@@@* @@. "
|
||||
echo " .%- -@@@@@:=@@@@ @@# "
|
||||
echo " .#- .%@@@@@@#. +@@@@@.#@@@@ @@@."
|
||||
echo " .*- .@@@@@@@@@@=. @@@@@@ @@@@@ @@@:"
|
||||
echo " :. .%@@@@@@@@@@@%. .@@@@@+:@@@@@ @@@-"
|
||||
echo " -@@@@@@@@@@@@@@@..@@@@@@.-@@@@@ .@@@-"
|
||||
echo " -@@@@@@@@@@%. .@@@@@@. @@@@@+ =@@@="
|
||||
echo " =@@@@@@@@* .@@@@@@. @@@@@@..@@@@-"
|
||||
echo " #@@@@@@@@-*@@@@@%..@@@@@@+ #@@@@-"
|
||||
echo " @@@@@@:.-@@@@@@. @@@@@@= %@@@@@."
|
||||
echo " .@@@@. *@@@@@@- .+@@@@@@-.@@@@@@+ "
|
||||
echo " %@@. =@@@@@*. +@@@@@@%.-@@@@@@% "
|
||||
echo " .@@ .@@@@@= :@@@@@@@@..@@@@@@@= "
|
||||
echo " =@.+@@@@@. -@@@@@@@*.:@@@@@@@*. "
|
||||
echo " %.*@@@@= .@@@@@@@-.:@@@@@@@+. "
|
||||
echo " ..@@@@= .@@@@@@: #@@@@@@@: "
|
||||
echo " .@@@@ +@@@@..%@@@@@+. "
|
||||
echo " .@@@. @@@@.:@@@@+. "
|
||||
echo " @@@. @@@. @@@* .@. "
|
||||
echo " :@@@ %@@..@@#. *@ "
|
||||
echo " -*: .@@* :@@. @@. -..@@ "
|
||||
echo " =@@@@@@.*@- :@% @* =@:=@# "
|
||||
echo " .@@@-+@@@@:%@..%- ...@%:@@: "
|
||||
echo " .@@. @@-%@: .%@@*@@%. "
|
||||
echo " :@@ :+ *@ *@@#*@@@. "
|
||||
echo " =@@@.@@@@ "
|
||||
echo " .*@@@:=@@@@: "
|
||||
echo " .@@@@:.@@@@@: "
|
||||
echo " .@@@@#.-@@@@@. "
|
||||
echo " #@@@@: =@@@@@- "
|
||||
echo " .@@@@@..@@@@@@* "
|
||||
echo " -@@@@@. @@@@@@#. "
|
||||
echo " -@@@@@ @@@@@@% "
|
||||
echo " @@@@@. #@@@@@@. "
|
||||
echo " :@@@@# =@@@@@@% "
|
||||
echo " @@@@@: @@@@@@@: "
|
||||
echo " *@@@@ @@@@@@@. "
|
||||
echo " .@@@@ @@@@@@@ "
|
||||
echo " #@@@. @@@@@@* "
|
||||
echo " @@@# @@@@@@@ "
|
||||
echo " .@@+=@@@@@@. "
|
||||
echo " *@@@@@@ "
|
||||
echo " :@@@@@= "
|
||||
echo " .@@@@@@. "
|
||||
echo " :@@@@@*. "
|
||||
echo " .=@@@@@- "
|
||||
echo " :+##+. "
|
||||
|
||||
echo -e "\e[92m"
|
||||
echo "Welcome to iamromulan's RGMII Toolkit script for Quectel RMxxx Series modems!"
|
||||
echo "Visit https://github.com/iamromulan for more!"
|
||||
echo -e "\e[0m"
|
||||
echo "Select an option:"
|
||||
echo -e "\e[0m"
|
||||
echo -e "\e[96m1) Send AT Commands\e[0m" # Cyan
|
||||
echo -e "\e[93m2) Install Simple Admin\e[0m" # Yellow
|
||||
echo -e "\e[95m3) Set Simpleadmin (admin) password\e[0m" # Light Purple
|
||||
echo -e "\e[94m4) Set Console/ttyd (root) password\e[0m" # Light Blue
|
||||
echo -e "\e[91m5) Uninstall Simple Admin\e[0m" # Light Red
|
||||
echo -e "\e[95m6) Simple Firewall Management\e[0m" # Light Purple
|
||||
echo -e "\e[94m7) Tailscale Management\e[0m" # Light Blue
|
||||
echo -e "\e[92m8) Install/Change or remove Daily Reboot Timer\e[0m" # Light Green
|
||||
echo -e "\e[96m9) Install/Uninstall CFUN 0 Fix\e[0m" # Cyan (repeated color for additional options)
|
||||
echo -e "\e[91m10) Uninstall Entware/OPKG\e[0m" # Light Red
|
||||
echo -e "\e[92m11) Install Speedtest.net CLI app (speedtest command)\e[0m" # Light Green
|
||||
echo -e "\e[92m12) Install Fast.com CLI app (fast command)(tops out at 40Mbps)\e[0m" # Light Green
|
||||
echo -e "\e[92m13) Install OpenSSH Server\e[0m" # Light Green
|
||||
echo -e "\e[93m14) Exit\e[0m" # Yellow (repeated color for exit option)
|
||||
read -p "Enter your choice: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
send_at_commands
|
||||
;;
|
||||
2)
|
||||
install_simple_admin
|
||||
;;
|
||||
3) set_simpleadmin_passwd
|
||||
;;
|
||||
4)
|
||||
set_root_passwd
|
||||
;;
|
||||
5)
|
||||
uninstall_simpleadmin_components
|
||||
;;
|
||||
6)
|
||||
configure_simple_firewall
|
||||
;;
|
||||
|
||||
7)
|
||||
tailscale_menu
|
||||
;;
|
||||
8)
|
||||
manage_reboot_timer
|
||||
;;
|
||||
9)
|
||||
manage_cfun_fix
|
||||
;;
|
||||
10)
|
||||
echo -e "\033[31mAre you sure you want to uninstall entware?\033[0m"
|
||||
echo -e "\033[31m1) Yes\033[0m"
|
||||
echo -e "\033[31m2) No\033[0m"
|
||||
read -p "Select an option (1 or 2): " user_choice
|
||||
|
||||
case $user_choice in
|
||||
1)
|
||||
# If yes, uninstall existing entware
|
||||
echo -e "\033[31mUninstalling existing entware...\033[0m"
|
||||
uninstall_entware # Assuming uninstall_entware is a defined function or command
|
||||
echo -e "\033[31mEntware has been uninstalled.\033[0m"
|
||||
;;
|
||||
2)
|
||||
# If no, exit the script
|
||||
echo -e "\033[31mUninstallation cancelled.\033[0m"
|
||||
exit # Use 'exit' to terminate the script outside a loop
|
||||
;;
|
||||
*)
|
||||
# Handle invalid input
|
||||
echo -e "\033[31mInvalid option. Please select 1 or 2.\033[0m"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
11)
|
||||
ensure_entware_installed
|
||||
echo -e "\e[1;32mInstalling Speedtest.net CLI (speedtest command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
tar -xzf ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm ookla-speedtest-1.2.0-linux-armhf.tgz
|
||||
rm speedtest.md
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/speedtest /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mSpeedtest CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'speedtest'\e[0m"
|
||||
echo -e "\e[1;32mNote that it will not work unless you login to the root account first\e[0m"
|
||||
echo -e "\e[1;32mNormaly only an issue in adb, ttyd and ssh you are forced to login\e[0m"
|
||||
echo -e "\e[1;32mIf in adb just type login and then try to run the speedtest command\e[0m"
|
||||
;;
|
||||
12)
|
||||
echo -e "\e[1;32mInstalling fast.com CLI (fast command)\e[0m"
|
||||
remount_rw
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
cd /usrdata/root/bin
|
||||
wget -O fast https://github.com/ddo/fast/releases/download/v0.0.4/fast_linux_arm && chmod +x fast
|
||||
cd /
|
||||
ln -sf /usrdata/root/bin/fast /bin
|
||||
remount_ro
|
||||
echo -e "\e[1;32mFast.com CLI (speedtest command) installed!!\e[0m"
|
||||
echo -e "\e[1;32mTry running the command 'fast'\e[0m"
|
||||
echo -e "\e[1;32mThe fast.com test tops out at 40Mbps on the modem\e[0m"
|
||||
;;
|
||||
13)
|
||||
install_sshd
|
||||
;;
|
||||
14)
|
||||
echo -e "\e[1;32mGoodbye!\e[0m"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid option\e[0m"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
114
old/download
Normal file
114
old/download
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Determine the absolute path of the script
|
||||
SCRIPT_PATH=$(realpath "$0")
|
||||
|
||||
download() {
|
||||
if [ "$1" = "github" ]; then
|
||||
download_github_directory "$2" "$3"
|
||||
else
|
||||
download_file "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
download_file() {
|
||||
url="$1"
|
||||
output="${2:-$(basename "$url")}"
|
||||
|
||||
echo "Attempting to download file from URL: $url"
|
||||
echo "Saving to output: $output"
|
||||
|
||||
# Ensure the output directory exists
|
||||
mkdir -p "$(dirname "$output")"
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
curl -L -o "$output" "$url"
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
wget -O "$output" "$url"
|
||||
else
|
||||
echo "Error: Neither curl nor wget is available."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download_github_directory() {
|
||||
github_url="$1"
|
||||
output_dir="${2:-.}" # Set output directory to the provided parameter or current directory
|
||||
|
||||
repo_info=$(echo "$github_url" | sed -n 's|https://github.com/\([^/]*\)/\([^/]*\)/tree/\([^/]*\)/\(.*\)|\1 \2 \3 \4|p')
|
||||
owner=$(echo "$repo_info" | cut -d' ' -f1)
|
||||
repo=$(echo "$repo_info" | cut -d' ' -f2)
|
||||
branch=$(echo "$repo_info" | cut -d' ' -f3)
|
||||
directory=$(echo "$repo_info" | cut -d' ' -f4)
|
||||
|
||||
echo "Owner: $owner, Repo: $repo, Branch: $branch, Directory: $directory"
|
||||
|
||||
if [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$branch" ] || [ -z "$directory" ]; then
|
||||
echo "Error: Invalid GitHub URL."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Output directory set to: $output_dir"
|
||||
|
||||
api_url="https://api.github.com/repos/$owner/$repo/contents/$directory?ref=$branch"
|
||||
echo "Fetching directory contents from API URL: $api_url"
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
contents=$(curl -s -H "Accept: application/vnd.github.v3+json" "$api_url")
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
contents=$(wget -qO- --header="Accept: application/vnd.github.v3+json" "$api_url")
|
||||
else
|
||||
echo "Error: Neither curl nor wget is available."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "API Response Contents:"
|
||||
echo "$contents"
|
||||
|
||||
# Use awk to parse JSON content and prepare commands
|
||||
echo "$contents" | awk -v output_dir="$output_dir" -v owner="$owner" -v repo="$repo" -v branch="$branch" -v script_path="$SCRIPT_PATH" '
|
||||
BEGIN {
|
||||
RS="},"; FS=","; # Set Record Separator to "}," and Field Separator to ","
|
||||
}
|
||||
/"type": "file"/ {
|
||||
file_path = ""; download_url = "";
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if ($i ~ /"path": "/) {
|
||||
gsub(/.*"path": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
file_path = $i;
|
||||
}
|
||||
if ($i ~ /"download_url": "/) {
|
||||
gsub(/.*"download_url": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
download_url = $i;
|
||||
}
|
||||
}
|
||||
if (file_path && download_url) {
|
||||
output_file_path = output_dir "/" file_path;
|
||||
print "Calling download_file for:", download_url, "to", output_file_path;
|
||||
system("'"$SCRIPT_PATH"'" " \"" download_url "\" \"" output_file_path "\"");
|
||||
}
|
||||
}
|
||||
/"type": "dir"/ {
|
||||
sub_dir = "";
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if ($i ~ /"path": "/) {
|
||||
gsub(/.*"path": "/, "", $i);
|
||||
gsub(/".*/, "", $i);
|
||||
sub_dir = $i;
|
||||
}
|
||||
}
|
||||
if (sub_dir) {
|
||||
print "Calling download_github_directory for sub-directory:", sub_dir;
|
||||
system("'"$SCRIPT_PATH"'" " github \"https://github.com/" owner "/" repo "/tree/" branch "/" sub_dir "\" \"" output_dir "\"");
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
echo "Usage: download <type> <url> [output_directory]"
|
||||
exit 1
|
||||
else
|
||||
download "$@"
|
||||
fi
|
||||
167
old/installentware.sh
Normal file
167
old/installentware.sh
Normal file
@@ -0,0 +1,167 @@
|
||||
#!/bin/sh
|
||||
# Modified by iamromulan to set up a proper entware environment for Quectel RM5xx series m.2 modems
|
||||
TYPE='generic'
|
||||
#|---------|-----------------|
|
||||
#| TARGET | Quectel Modem |
|
||||
#| ARCH | armv7sf-k3.2 |
|
||||
#| LOADER | ld-linux.so.3 |
|
||||
#| GLIBC | 2.27 |
|
||||
#|---------|-----------------|
|
||||
unset LD_LIBRARY_PATH
|
||||
unset LD_PRELOAD
|
||||
ARCH=armv7sf-k3.2
|
||||
LOADER=ld-linux.so.3
|
||||
GLIBC=2.27
|
||||
PRE_OPKG_PATH=$(which opkg)
|
||||
|
||||
# Remount filesystem as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
create_opt_mount() {
|
||||
# Bind /usrdata/opt to /opt
|
||||
echo -e '\033[32mInfo: Setting up /opt mount to /usrdata/opt...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/opt.mount
|
||||
[Unit]
|
||||
Description=Bind /usrdata/opt to /opt
|
||||
|
||||
[Mount]
|
||||
What=/usrdata/opt
|
||||
Where=/opt
|
||||
Type=none
|
||||
Options=bind
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl start opt.mount
|
||||
|
||||
# Additional systemd service to ensure opt.mount starts at boot
|
||||
echo -e '\033[32mInfo: Creating service to start opt.mount at boot...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/start-opt-mount.service
|
||||
[Unit]
|
||||
Description=Ensure opt.mount is started at boot
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start opt.mount
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/start-opt-mount.service /lib/systemd/system/multi-user.target.wants/start-opt-mount.service
|
||||
}
|
||||
|
||||
if [ -n "$PRE_OPKG_PATH" ]; then
|
||||
# Automatically rename the existing opkg binary
|
||||
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
||||
echo -e "\033[32mFactory/Already existing opkg has been renamed to opkg_old.\033[0m"
|
||||
else
|
||||
echo "Info: no existing opkg binary detected, proceeding with installation"
|
||||
fi
|
||||
|
||||
echo -e '\033[32mInfo: Creating /opt mount pointed to /usrdata/opt ...\033[0m'
|
||||
create_opt_mount
|
||||
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
||||
# no need to create many folders. entware-opt package creates most
|
||||
for folder in bin etc lib/opkg tmp var/lock
|
||||
do
|
||||
if [ -d "/opt/$folder" ]; then
|
||||
echo -e '\033[31mWarning: Folder /opt/$folder exists!\033[0m'
|
||||
echo -e '\033[31mWarning: If something goes wrong please clean /opt folder and try again.\033[0m'
|
||||
else
|
||||
mkdir -p /opt/$folder
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e '\033[32mInfo: Opkg package manager deployment...\033[0m'
|
||||
URL=http://bin.entware.net/${ARCH}/installer
|
||||
wget $URL/opkg -O /opt/bin/opkg
|
||||
chmod 755 /opt/bin/opkg
|
||||
wget $URL/opkg.conf -O /opt/etc/opkg.conf
|
||||
|
||||
echo -e '\033[32mInfo: Basic packages installation...\033[0m'
|
||||
/opt/bin/opkg update
|
||||
/opt/bin/opkg install entware-opt
|
||||
|
||||
# Fix for multiuser environment
|
||||
chmod 777 /opt/tmp
|
||||
|
||||
for file in passwd group shells shadow gshadow; do
|
||||
if [ $TYPE = 'generic' ]; then
|
||||
if [ -f /etc/$file ]; then
|
||||
ln -sf /etc/$file /opt/etc/$file
|
||||
else
|
||||
[ -f /opt/etc/$file.1 ] && cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
else
|
||||
if [ -f /opt/etc/$file.1 ]; then
|
||||
cp /opt/etc/$file.1 /opt/etc/$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ -f /etc/localtime ] && ln -sf /etc/localtime /opt/etc/localtime
|
||||
|
||||
# Create and enable rc.unslung service
|
||||
echo -e '\033[32mInfo: Creating rc.unslung (Entware init.d service)...\033[0m'
|
||||
cat <<EOF > /lib/systemd/system/rc.unslung.service
|
||||
[Unit]
|
||||
Description=Start Entware services
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Add a delay to give /opt time to mount
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/opt/etc/init.d/rc.unslung start
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
ln -s /lib/systemd/system/rc.unslung.service /lib/systemd/system/multi-user.target.wants/rc.unslung.service
|
||||
systemctl start rc.unslung.service
|
||||
echo -e '\033[32mInfo: Congratulations!\033[0m'
|
||||
echo -e '\033[32mInfo: If there are no errors above then Entware was successfully initialized.\033[0m'
|
||||
echo -e '\033[32mInfo: Add /opt/bin & /opt/sbin to $PATH variable\033[0m'
|
||||
ln -sf /opt/bin/opkg /bin
|
||||
echo -e '\033[32mInfo: Patching Quectel Login Binary\033[0m'
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Install basic and useful utilites
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
# Remount filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
105
old/installopkg.sh
Normal file
105
old/installopkg.sh
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
|
||||
#|---------|-------------------------|
|
||||
#| TARGET | SDXLEMUR |
|
||||
#| ARCH | arm_cortex-a7_neon-vfpv4|
|
||||
#|---------|-------------------------|
|
||||
|
||||
# Based on entware, heavily modified by iamromulan
|
||||
# This script sets up a custom opkg installation system for the SDXLEMUR platform
|
||||
# The primary feed for this will be my feed and will be a combo of modified IPK files from multiple sources
|
||||
# opkg is from entware and expects /opt to exist
|
||||
# /opt will be setup as an overlay of lower / and upper /usrdata/rootfs-upper
|
||||
# Most likely several mount binds will be setup at / to point back to /opt the overlay
|
||||
# The real /lib/systemd will need to be able to be written to so we may bind that within /opt
|
||||
# In active development; will decide if the entware feed gets re added later
|
||||
|
||||
|
||||
ARCH=arm_cortex-a7_neon-vfpv4
|
||||
#ARCH=armv7sf-k3.2
|
||||
PRE_OPKG_PATH=$(which opkg)
|
||||
URL=https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development-SDXLEMUR/opkg-feed/installer
|
||||
|
||||
# Remount filesystem as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
# Will need to edit this. Will be an overlay instead of bind mount
|
||||
# The package sdxlemur-mount-fix will make this run at boot
|
||||
create_opt_overlay() {
|
||||
|
||||
[ ! -d "/opt" ] && mkdir /opt
|
||||
[ ! -d "/usrdata/rootfs-upper" ] && mkdir /usrdata/rootfs-upper
|
||||
[ ! -d "/usrdata/rootfs-work" ] && mkdir /usrdata/rootfs-work
|
||||
|
||||
mount -t overlay overlay_root -o lowerdir=/,upperdir=/usrdata/rootfs-upper,workdir=/usrdata/rootfs-work /opt
|
||||
|
||||
# add additional mount binds and dir
|
||||
|
||||
}
|
||||
|
||||
# Account for existing opkg binary on the RM502Q-AE
|
||||
if [ -n "$PRE_OPKG_PATH" ]; then
|
||||
# Automatically rename the existing opkg binary
|
||||
mv "$PRE_OPKG_PATH" "${PRE_OPKG_PATH}_old"
|
||||
echo -e "\033[32mFactory/Already existing opkg has been renamed to opkg_old.\033[0m"
|
||||
else
|
||||
echo "Info: no existing opkg binary detected, proceeding with installation"
|
||||
fi
|
||||
|
||||
echo -e '\033[32mInfo: Creating /opt overlayfs with lower / and upper /usrdata/rootfs-upper \033[0m'
|
||||
create_opt_overlay
|
||||
|
||||
echo -e '\033[32mInfo: Proceeding with main installation ...\033[0m'
|
||||
echo -e '\033[32mInfo: Opkg package manager deployment...\033[0m'
|
||||
|
||||
wget $URL/opkg -O /opt/bin/opkg
|
||||
chmod 755 /opt/bin/opkg
|
||||
wget $URL/opkg.conf -O /opt/etc/opkg.conf
|
||||
|
||||
echo -e '\033[32mInfo: Basic packages installation...\033[0m'
|
||||
/opt/bin/opkg update
|
||||
#/opt/bin/opkg install entware-opt #Will revist this and its need
|
||||
/opt/bin/opkg install sdxlemur-factory-packages
|
||||
|
||||
# Fix for multiuser environment
|
||||
chmod 777 /opt/tmp
|
||||
|
||||
|
||||
echo -e '\033[32mInfo: Add /opt/bin & /opt/sbin to $PATH variable\033[0m'
|
||||
ln -sf /opt/bin/opkg /bin
|
||||
echo -e '\033[32mInfo: Patching Quectel Login Binary\033[0m'
|
||||
opkg update && opkg install shadow-login shadow-passwd shadow-useradd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mPackage installation failed. Please check your internet connection and try again.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace the login and passwd binaries and set home for root to a writable directory
|
||||
rm /opt/etc/shadow
|
||||
rm /opt/etc/passwd
|
||||
cp /etc/shadow /opt/etc/
|
||||
cp /etc/passwd /opt/etc
|
||||
mkdir /usrdata/root
|
||||
mkdir /usrdata/root/bin
|
||||
touch /usrdata/root/.profile
|
||||
echo "# Set PATH for all shells" > /usrdata/root/.profile
|
||||
echo "export PATH=/bin:/usr/sbin:/usr/bin:/sbin:/opt/sbin:/opt/bin:/usrdata/root/bin" >> /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
sed -i '1s|/home/root:/bin/sh|/usrdata/root:/bin/bash|' /opt/etc/passwd
|
||||
rm /bin/login /usr/bin/passwd
|
||||
ln -sf /opt/bin/login /bin
|
||||
ln -sf /opt/bin/passwd /usr/bin/
|
||||
ln -sf /opt/bin/useradd /usr/bin/
|
||||
echo -e "\e[1;31mPlease set the root password.\e[0m"
|
||||
/usr/bin/passwd
|
||||
|
||||
# Install basic and useful utilites
|
||||
opkg install mc htop dfc lsof
|
||||
ln -sf /opt/bin/mc /bin
|
||||
ln -sf /opt/bin/htop /bin
|
||||
ln -sf /opt/bin/dfc /bin
|
||||
ln -sf /opt/bin/lsof /bin
|
||||
# Remount filesystem as read-only
|
||||
mount -o remount,ro /
|
||||
echo -e '\033[32mInfo: Congratulations!\033[0m'
|
||||
echo -e '\033[32mInfo: If there are no errors above then Entware was successfully initialized.\033[0m'
|
||||
1
old/simpleadmin/.rev
Normal file
1
old/simpleadmin/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
7
old/simpleadmin/console/.profile
Normal file
7
old/simpleadmin/console/.profile
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
#Path
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
#Post-login execution
|
||||
/usrdata/simpleadmin/console/menu/start_menu.sh
|
||||
150
old/simpleadmin/console/menu/LAN_settings.sh
Normal file
150
old/simpleadmin/console/menu/LAN_settings.sh
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
|
||||
CONFIG_FILE="/etc/data/mobileap_cfg.xml"
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
# Check and Install xml binary if not present
|
||||
check_and_install_xml() {
|
||||
if [ ! -f "/opt/bin/xml" ]; then
|
||||
echo "xml binary not found. Attempting to install xmlstarlet..."
|
||||
opkg update
|
||||
opkg install xmlstarlet
|
||||
# Verify installation
|
||||
if [ ! -f "/opt/bin/xml" ]; then
|
||||
echo "Failed to install xmlstarlet. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "xml binary is available."
|
||||
}
|
||||
|
||||
# Edit XML Value
|
||||
edit_xml_value() {
|
||||
local node="$1"
|
||||
local new_value="$2"
|
||||
/opt/bin/xml ed -L -u "$node" -v "$new_value" "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# Get Current XML Value
|
||||
get_current_value() {
|
||||
/opt/bin/xml sel -t -v "$1" "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# Enable/Disable Menu
|
||||
enable_disable_menu() {
|
||||
local node="$1"
|
||||
local current_value=$(get_current_value "$node")
|
||||
echo "Current status: $([ "$current_value" == "1" ] && echo "Enabled" || echo "Disabled")"
|
||||
echo "1. Enable"
|
||||
echo "2. Disable"
|
||||
read -p "Choose an option to toggle (1-2): " choice
|
||||
local new_value="$([ "$choice" == "1" ] && echo "1" || echo "0")"
|
||||
edit_xml_value "$node" "$new_value"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Edit Simple Value
|
||||
edit_simple_value() {
|
||||
local node="$1"
|
||||
local description="$2"
|
||||
local current=$(get_current_value "$node")
|
||||
echo "Current $description: $current"
|
||||
read -p "Enter new $description: " new_value
|
||||
edit_xml_value "$node" "$new_value"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Edit DHCP IP Range
|
||||
edit_dhcp_range() {
|
||||
local start_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/StartIP")
|
||||
local end_ip=$(get_current_value "//MobileAPLanCfg/DHCPCfg/EndIP")
|
||||
echo "Current Start IP: $start_ip"
|
||||
echo "Current End IP: $end_ip"
|
||||
read -p "Enter new Start IP: " new_start_ip
|
||||
read -p "Enter new End IP: " new_end_ip
|
||||
edit_xml_value "//MobileAPLanCfg/DHCPCfg/StartIP" "$new_start_ip"
|
||||
edit_xml_value "//MobileAPLanCfg/DHCPCfg/EndIP" "$new_end_ip"
|
||||
display_green "After making changes, please reboot to have them take effect."
|
||||
}
|
||||
|
||||
# Reboot the system
|
||||
reboot_system() {
|
||||
echo "Rebooting system..."
|
||||
atcmd 'AT+CFUN=1,1' # Ensure this command is correct for your system
|
||||
echo "System reboot initiated. Good luck."
|
||||
}
|
||||
|
||||
# Main Menu
|
||||
main_menu() {
|
||||
while true; do
|
||||
clear
|
||||
display_red "Warning, these changes can break access over the network. Know what you are doing, and be prepared to use ADB to fix this just in case."
|
||||
echo "Configuration Menu"
|
||||
echo "------------------"
|
||||
display_green "1. Edit Gateway IPV4 Address"
|
||||
display_green "2. Edit Gateway URL"
|
||||
display_green "3. Edit LAN DHCP Start/End Range"
|
||||
display_green "4. Edit LAN Subnet Mask"
|
||||
display_green "5. Edit DHCPv6 Base address"
|
||||
display_green "6. Toggle IPv4 NAT"
|
||||
display_green "7. Toggle IPv6 NAT"
|
||||
display_green "8. Toggle DHCP Server"
|
||||
display_green "9. Toggle DHCPv4"
|
||||
display_green "10. Toggle DHCPv6"
|
||||
display_green "11. Toggle WAN Autoconnect"
|
||||
display_green "12. Toggle WAN AutoReconnect"
|
||||
display_green "13. Toggle Roaming"
|
||||
display_green "14. Toggle WAN DNSv4 Passthrough"
|
||||
display_green "15. Toggle WAN DNSv6 Passthrough"
|
||||
display_green "16. Toggle IPPT NAT/Ability to access gateway while in IPPT mode"
|
||||
display_green "17. Toggle UPnP"
|
||||
display_green "18. Reboot System"
|
||||
display_green "19. Exit"
|
||||
echo
|
||||
read -p "Select an option (1-19): " option
|
||||
|
||||
case "$option" in
|
||||
1) edit_simple_value "//MobileAPLanCfg/APIPAddr" "Gateway IPV4 Address";;
|
||||
2) edit_simple_value "//MobileAPLanCfg/GatewayURL" "Gateway URL";;
|
||||
3) edit_dhcp_range;;
|
||||
4) edit_simple_value "//MobileAPLanCfg/SubNetMask" "LAN Subnet Mask";;
|
||||
5) edit_simple_value "//MobileAPLanCfg/ULAIPv6BaseAddr" "DHCPv6 Base Address";;
|
||||
6) enable_disable_menu "//MobileAPNatCfg/IPv4NATDisable";;
|
||||
7) enable_disable_menu "//MobileAPNatv6Cfg/EnableIPv6NAT";;
|
||||
8) enable_disable_menu "//MobileAPLanCfg/EnableDHCPServer";;
|
||||
9) enable_disable_menu "//MobileAPLanCfg/EnableIPV4";;
|
||||
10) enable_disable_menu "//MobileAPLanCfg/EnableIPV6";;
|
||||
11) enable_disable_menu "//MobileAPWanCfg/AutoConnect";;
|
||||
12) enable_disable_menu "//MobileAPWanCfg/ReConnect";;
|
||||
13) enable_disable_menu "//MobileAPWanCfg/Roaming";;
|
||||
14) enable_disable_menu "//Dhcpv4Cfg/EnableDhcpv4Dns";;
|
||||
15) enable_disable_menu "//Dhcpv6Cfg/EnableDhcpv6Dns";;
|
||||
16) enable_disable_menu "//IPPassthroughFeatureWithNAT";;
|
||||
17) enable_disable_menu "//MobileAPSrvcCfg/UPnP";;
|
||||
18) reboot_system;;
|
||||
19) break;;
|
||||
*) echo "Invalid option. Please try again.";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Start by checking and installing xml if necessary, then mount filesystem as rw and run the menu
|
||||
mount -o remount,rw /
|
||||
check_and_install_xml
|
||||
main_menu
|
||||
129
old/simpleadmin/console/menu/sfirewall_settings.sh
Normal file
129
old/simpleadmin/console/menu/sfirewall_settings.sh
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
set_portblocks() {
|
||||
current_ports_line=$(grep '^PORTS=' "$SIMPLE_FIREWALL_SCRIPT")
|
||||
ports=$(echo "$current_ports_line" | cut -d'=' -f2 | tr -d '()' | tr ' ' '\n' | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mCurrent configured ports:\e[0m"
|
||||
echo "$ports" | awk '{print NR") "$0}'
|
||||
|
||||
while true; do
|
||||
echo -e "\e[1;32mEnter a port number to add/remove, or type 'done' or 'exit' to finish:\e[0m"
|
||||
read port
|
||||
if [ "$port" = "done" ] || [ "$port" = "exit" ]; then
|
||||
if [ "$port" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting without making changes...\e[0m"
|
||||
return
|
||||
fi
|
||||
break
|
||||
elif ! echo "$port" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
elif echo "$ports" | grep -q "^$port\$"; then
|
||||
ports=$(echo "$ports" | grep -v "^$port\$")
|
||||
echo -e "\e[1;32mPort $port removed.\e[0m"
|
||||
else
|
||||
ports=$(echo "$ports"; echo "$port" | grep -o '[0-9]\+')
|
||||
echo -e "\e[1;32mPort $port added.\e[0m"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$port" != "exit" ]; then
|
||||
new_ports_line="PORTS=($(echo "$ports" | tr '\n' ' '))"
|
||||
sed -i "s/$current_ports_line/$new_ports_line/" "$SIMPLE_FIREWALL_SCRIPT"
|
||||
fi
|
||||
}
|
||||
|
||||
set_ttl(){
|
||||
# TTL configuration code
|
||||
ttl_value=$(cat /usrdata/simplefirewall/ttlvalue)
|
||||
if [ "$ttl_value" -eq 0 ]; then
|
||||
echo -e "\e[1;31mTTL is not set.\e[0m"
|
||||
else
|
||||
echo -e "\e[1;32mTTL value is set to $ttl_value.\e[0m"
|
||||
fi
|
||||
|
||||
echo -e "\e[1;31mType 'exit' to cancel.\e[0m"
|
||||
read -p "What do you want the TTL value to be: " new_ttl_value
|
||||
if [ "$new_ttl_value" = "exit" ]; then
|
||||
echo -e "\e[1;31mExiting TTL configuration...\e[0m"
|
||||
return
|
||||
elif ! echo "$new_ttl_value" | grep -qE '^[0-9]+$'; then
|
||||
echo -e "\e[1;31mInvalid input: Please enter a numeric value.\e[0m"
|
||||
return
|
||||
else
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
echo "$new_ttl_value" > /usrdata/simplefirewall/ttlvalue
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
echo -e "\033[0;32mTTL value updated to $new_ttl_value.\033[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
# function to configure the fetures of simplefirewall
|
||||
simple_firewall_menu() {
|
||||
if [ ! -f "$SIMPLE_FIREWALL_SCRIPT" ]; then
|
||||
display_random_color "Simplefirewall is not installed, would you like to install it?"
|
||||
display_green "1) Yes"
|
||||
display_red "2) No"
|
||||
read -p "Enter your choice (1-2): " install_choice
|
||||
|
||||
case $install_choice in
|
||||
1)
|
||||
install_simple_firewall
|
||||
;;
|
||||
2)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
display_red "Invalid choice. Please select either 1 or 2."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
display_random_color "Configure Simple Firewall:"
|
||||
display_green "1) Configure incoming port block"
|
||||
display_green "2) Configure TTL"
|
||||
display_green "3) Exit to Main Menu"
|
||||
read -p "Enter your choice (1-2): " menu_choice
|
||||
|
||||
case $menu_choice in
|
||||
1)
|
||||
set_portblocks
|
||||
;;
|
||||
2)
|
||||
set_ttl
|
||||
;;
|
||||
3)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
echo -e "\e[1;31mInvalid choice. Please select either 1 or 2.\e[0m"
|
||||
;;
|
||||
esac
|
||||
|
||||
systemctl restart simplefirewall
|
||||
echo -e "\e[1;32mFirewall configuration updated.\e[0m"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
mount -o remount,rw /
|
||||
simple_firewall_menu
|
||||
118
old/simpleadmin/console/menu/start_menu.sh
Normal file
118
old/simpleadmin/console/menu/start_menu.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define executable files path
|
||||
MENU_SH=/usrdata/simpleadmin/console/menu
|
||||
|
||||
# Display Messages in Colors
|
||||
display_random_color() {
|
||||
local msg="$1"
|
||||
local colors=(33 34 35 36 37) # ANSI color codes for yellow, blue, magenta, cyan, white
|
||||
local num_colors=${#colors[@]}
|
||||
local random_color_index=$(($RANDOM % num_colors)) # Pick a random index from the colors array
|
||||
echo -e "\033[${colors[$random_color_index]}m$msg\033[0m"
|
||||
}
|
||||
|
||||
display_green() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
display_red() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
|
||||
# Menus
|
||||
|
||||
toolkit_menu() {
|
||||
while true; do
|
||||
display_random_color "Run a Toolkit version"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_green "1. Get and run the Toolkit"
|
||||
display_random_color "2. Get and run the Development/unstable Toolkit"
|
||||
display_random_color "3. Exit (Enter Root Shell)"
|
||||
echo
|
||||
read -p "Select an option (1-3): " option
|
||||
|
||||
case "$option" in
|
||||
1) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/SDXLEMUR/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||
2) cd /tmp && wget -O RMxxx_rgmii_toolkit.sh https://raw.githubusercontent.com/iamromulan/quectel-rgmii-toolkit/development-SDXLEMUR/RMxxx_rgmii_toolkit.sh && chmod +x RMxxx_rgmii_toolkit.sh && ./RMxxx_rgmii_toolkit.sh && cd / ;;
|
||||
3) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
apps_menu() {
|
||||
while true; do
|
||||
display_random_color "Run a modem App"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_random_color "1. Open File Browser/Editor (mc)"
|
||||
display_random_color "2. View Used/Available space"
|
||||
display_random_color "3. Open Task Manager/View CPU Load"
|
||||
display_random_color "4. Run speedtest.net test"
|
||||
display_random_color "5. Run fast.com test (30Mbps max)"
|
||||
display_green "6. Go Back"
|
||||
echo
|
||||
read -p "Select an option (1-6): " option
|
||||
|
||||
case "$option" in
|
||||
1) mc ;;
|
||||
2) dfc ;;
|
||||
3) htop ;;
|
||||
4) speedtest ;;
|
||||
5) fast ;;
|
||||
6) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
settings_menu() {
|
||||
while true; do
|
||||
display_random_color "Welcome to" && display_green "iamromulan's" && display_random_color "Simple Console Menu"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_green "1. LAN Settings"
|
||||
display_green "2. simplefirewall settings (TTL and Port Block)"
|
||||
display_green "3. Change simpleadmin (admin) password"
|
||||
display_green "4. Change root password (shell/ssh/console)"
|
||||
display_green "5. Go back"
|
||||
echo
|
||||
read -p "Select an option (1-5): " option
|
||||
|
||||
case "$option" in
|
||||
1) $MENU_SH/LAN_settings.sh ;;
|
||||
2) $MENU_SH/sfirewall_settings.sh ;;
|
||||
3) simplepasswd ;;
|
||||
4) passwd ;;
|
||||
5) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main_menu() {
|
||||
while true; do
|
||||
display_green "Welcome to iamromulan's Simple Console Menu"
|
||||
display_green "To get back to this from the root shell, just type 'menu'"
|
||||
display_green "Select an option:"
|
||||
echo "------------------"
|
||||
display_random_color "1. Apps"
|
||||
display_random_color "2. Settings"
|
||||
display_random_color "3. Toolkit"
|
||||
display_random_color "4. Exit (Enter Root Shell)"
|
||||
echo
|
||||
read -p "Select an option (1-4): " option
|
||||
|
||||
case "$option" in
|
||||
1) apps_menu ;;
|
||||
2) settings_menu ;;
|
||||
3) toolkit_menu ;;
|
||||
4) break ;;
|
||||
*) echo "Invalid option. Please try again." ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main_menu
|
||||
27
old/simpleadmin/console/services/ethernet_watchdog.sh
Normal file
27
old/simpleadmin/console/services/ethernet_watchdog.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the command to execute when the ethernet port breaks
|
||||
command_to_execute="/usrdata/socat-at-bridge/atcmd 'AT+CFUN=1,1'"
|
||||
|
||||
# Define the monitoring function
|
||||
watch() {
|
||||
while true; do
|
||||
# Extract the last 60 lines of dmesg and count the specific pattern occurrences
|
||||
count=$(dmesg | tail -60 | grep -e "eth0: cmd = 0xff, should be 0x47" -e "eth0: pci link is down" | grep -c "eth0")
|
||||
|
||||
# Check if the count of patterns is 4 or more
|
||||
if [ "$count" -ge 4 ]; then
|
||||
echo "Condition met, executing command..."
|
||||
eval "$command_to_execute"
|
||||
# Optionally, add a break here if you want the script to stop after executing the command
|
||||
# break
|
||||
fi
|
||||
|
||||
# Sleep for 3 seconds before checking again
|
||||
sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
# Initial delay before starting monitoring
|
||||
sleep 30
|
||||
watch
|
||||
28
old/simpleadmin/console/services/ping_watchdog.sh
Normal file
28
old/simpleadmin/console/services/ping_watchdog.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the hostname or IP address to ping
|
||||
HOSTNAME="google.com"
|
||||
|
||||
# Number of pings to attempt
|
||||
PING_COUNT=6
|
||||
|
||||
# Initialize a counter for successful pings
|
||||
success_count=0
|
||||
|
||||
# Attempt to ping the specified number of times
|
||||
for i in $(seq 1 $PING_COUNT); do
|
||||
# Ping the hostname with a timeout of 1 second per ping
|
||||
if ping -c 1 -W 1 $HOSTNAME &> /dev/null; then
|
||||
((success_count++))
|
||||
else
|
||||
echo "Ping attempt $i failed."
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if all pings failed
|
||||
if [ $success_count -eq 0 ]; then
|
||||
echo "All $PING_COUNT ping attempts failed, executing AT command."
|
||||
/bin/atcmd 'AT+CFUN=1,1'
|
||||
else
|
||||
echo "$success_count out of $PING_COUNT ping attempts were successful."
|
||||
fi
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Ping Watchdog Service
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 60 # Sleep for 60 seconds to ensure the network is ready
|
||||
ExecStart=/usrdata/simpleadmin/console/services/ping_watchdog.sh
|
||||
Restart=on-failure
|
||||
RestartSec=30s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
99
old/simpleadmin/console/ttyd.bash
Normal file
99
old/simpleadmin/console/ttyd.bash
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if /usrdata/socat-at-bridge/atcmd exists
|
||||
if [ -f "/usrdata/socat-at-bridge/atcmd" ]; then
|
||||
# Read the serial number
|
||||
serial_number=$(/usrdata/socat-at-bridge/atcmd 'AT+EGMR=0,5' | grep '+EGMR:' | cut -d '"' -f2)
|
||||
# Read the firmware revision
|
||||
firmware_revision=$(/usrdata/socat-at-bridge/atcmd 'AT+QGMR' | grep -o 'RM[0-9A-Z].*')
|
||||
else
|
||||
serial_number="UNKNOWN"
|
||||
firmware_revision="UNKNOWN"
|
||||
fi
|
||||
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
# Start your Actual echo output here, 17 lines omitted for mobile compatibility. ttyd font needs to be size 25.
|
||||
# Echo "Logo"
|
||||
echo " .%+: "
|
||||
echo " .*@@@-. "
|
||||
echo " :@@@@- "
|
||||
echo " @@@@#. "
|
||||
echo " -@@@@#. "
|
||||
echo " :. %@@@@: -# "
|
||||
echo " .+- #@@@@%.+@- "
|
||||
echo " .#- . +@@@@# #@- "
|
||||
echo " -@*@*@% @@@@@::@@= "
|
||||
echo ".+%@@@@@@@@@%=. =@@@@# #@@- .. "
|
||||
echo " .@@@@@: :@@@@@ =@@@..%= "
|
||||
echo " -::@-.+. @@@@@.=@@@- =@- "
|
||||
echo " .@- .@@@@@:.@@@* @@. "
|
||||
echo " .%- -@@@@@:=@@@@ @@# "
|
||||
echo " .#- .%@@@@@@#. +@@@@@.#@@@@ @@@."
|
||||
echo " .*- .@@@@@@@@@@=. @@@@@@ @@@@@ @@@:"
|
||||
echo " :. .%@@@@@@@@@@@%. .@@@@@+:@@@@@ @@@-"
|
||||
echo " -@@@@@@@@@@@@@@@..@@@@@@.-@@@@@ .@@@-"
|
||||
echo " -@@@@@@@@@@%. .@@@@@@. @@@@@+ =@@@="
|
||||
echo " =@@@@@@@@* .@@@@@@. @@@@@@..@@@@-"
|
||||
echo " #@@@@@@@@-*@@@@@%..@@@@@@+ #@@@@-"
|
||||
echo " @@@@@@:.-@@@@@@. @@@@@@= %@@@@@."
|
||||
echo " .@@@@. *@@@@@@- .+@@@@@@-.@@@@@@+ "
|
||||
echo " %@@. =@@@@@*. +@@@@@@%.-@@@@@@% "
|
||||
echo " .@@ .@@@@@= :@@@@@@@@..@@@@@@@= "
|
||||
echo " =@.+@@@@@. -@@@@@@@*.:@@@@@@@*. "
|
||||
echo " %.*@@@@= .@@@@@@@-.:@@@@@@@+. "
|
||||
echo " ..@@@@= .@@@@@@: #@@@@@@@: "
|
||||
echo " .@@@@ +@@@@..%@@@@@+. "
|
||||
echo " .@@@. @@@@.:@@@@+. "
|
||||
echo " @@@. @@@. @@@* .@. "
|
||||
echo " :@@@ %@@..@@#. *@ "
|
||||
echo " -*: .@@* :@@. @@. -..@@ "
|
||||
echo " =@@@@@@.*@- :@% @* =@:=@# "
|
||||
echo " .@@@-+@@@@:%@..%- ...@%:@@: "
|
||||
echo " .@@. @@-%@: .%@@*@@%. "
|
||||
echo " :@@ :+ *@ *@@#*@@@. "
|
||||
echo " =@@@.@@@@ "
|
||||
echo " .*@@@:=@@@@: "
|
||||
echo " .@@@@:.@@@@@: "
|
||||
echo " .@@@@#.-@@@@@. "
|
||||
echo " #@@@@: =@@@@@- "
|
||||
echo " .@@@@@..@@@@@@* "
|
||||
echo " -@@@@@. @@@@@@#. "
|
||||
echo " -@@@@@ @@@@@@% "
|
||||
echo " @@@@@. #@@@@@@. "
|
||||
echo " :@@@@# =@@@@@@% "
|
||||
echo " @@@@@: @@@@@@@: "
|
||||
echo " *@@@@ @@@@@@@. "
|
||||
echo " .@@@@ @@@@@@@ "
|
||||
echo " #@@@. @@@@@@* "
|
||||
echo " @@@# @@@@@@@ "
|
||||
echo " .@@+=@@@@@@. "
|
||||
echo " *@@@@@@ "
|
||||
echo " :@@@@@= "
|
||||
echo " .@@@@@@. "
|
||||
echo " :@@@@@*. "
|
||||
echo " .=@@@@@- "
|
||||
echo " :+##+. "
|
||||
echo "=============================================================="
|
||||
echo "TTYd session file by iamromulan v1.1"
|
||||
echo "Firmware Revision: $firmware_revision"
|
||||
echo "Serial Number: $serial_number"
|
||||
echo "=============================================================="
|
||||
|
||||
# Start a login session
|
||||
exec /bin/login
|
||||
BIN
old/simpleadmin/htpasswd
Normal file
BIN
old/simpleadmin/htpasswd
Normal file
Binary file not shown.
47
old/simpleadmin/lighttpd.conf
Normal file
47
old/simpleadmin/lighttpd.conf
Normal file
@@ -0,0 +1,47 @@
|
||||
server.modules = (
|
||||
"mod_redirect",
|
||||
"mod_cgi",
|
||||
"mod_proxy",
|
||||
"mod_openssl",
|
||||
"mod_authn_file",
|
||||
)
|
||||
|
||||
server.username = "www-data"
|
||||
server.groupname = "dialout"
|
||||
|
||||
server.port = 80
|
||||
server.document-root = "/usrdata/simpleadmin/www"
|
||||
index-file.names = ( "index.html" )
|
||||
|
||||
auth.backend = "htpasswd"
|
||||
auth.backend.htpasswd.userfile = "/opt/etc/.htpasswd"
|
||||
|
||||
$SERVER["socket"] == "0.0.0.0:443" {
|
||||
ssl.engine = "enable"
|
||||
ssl.privkey= "/usrdata/simpleadmin/server.key"
|
||||
ssl.pemfile= "/usrdata/simpleadmin/server.crt"
|
||||
ssl.acme-tls-1 = "/etc/simpleadmin/dehydrated/tls-alpn-01"
|
||||
ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # (lighttpd 1.4.56 default; recommended to accept only TLSv1.2 and TLSv1.3)
|
||||
auth.require = ( "/" => (
|
||||
"method" => "basic",
|
||||
"realm" => "Authorized users only",
|
||||
"require" => "valid-user"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
# Redirect everything to https
|
||||
$HTTP["scheme"] == "http" {
|
||||
url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
|
||||
}
|
||||
|
||||
# Anything in /cgi-bin will be run as a script
|
||||
$HTTP["url"] =~ "/cgi-bin/" {
|
||||
cgi.assign = ( "" => "" )
|
||||
}
|
||||
|
||||
# Handle proxy to ttyd if it's running
|
||||
$HTTP["url"] =~ "(^/console)" {
|
||||
proxy.header = ("map-urlpath" => ( "/console" => "/" ), "upgrade" => "enable" )
|
||||
proxy.server = ( "" => ("" => ( "host" => "127.0.0.1", "port" => 8080 )))
|
||||
}
|
||||
60
old/simpleadmin/script/create_watchcat.sh
Normal file
60
old/simpleadmin/script/create_watchcat.sh
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Function to create and run the Watchcat script
|
||||
create_and_run_watchcat_script() {
|
||||
local ip=$1
|
||||
local timeout=$2
|
||||
local failure_count=$3
|
||||
local script_path="/usrdata/simpleadmin/script/watchcat.sh"
|
||||
|
||||
# Create the script with the watchcat logic
|
||||
sudo cat << EOF > $script_path
|
||||
#!/bin/sh
|
||||
|
||||
failures=0
|
||||
|
||||
while :; do
|
||||
if ping -c 1 $ip > /dev/null 2>&1; then
|
||||
failures=0
|
||||
else
|
||||
failures=\$((failures + 1))
|
||||
if [ "\$failures" -ge "$failure_count" ]; then
|
||||
echo "Rebooting system due to \$failures consecutive ping failures."
|
||||
/sbin/reboot
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
sleep $timeout
|
||||
done
|
||||
EOF
|
||||
|
||||
# Make the watchcat script executable
|
||||
chmod +x $script_path
|
||||
|
||||
# Create a JSON to be fetched later
|
||||
echo "{\"enabled\": true, \"track_ip\": \"$ip\", \"ping_timeout\": $timeout, \"ping_failure_count\": $failure_count}" > /usrdata/simpleadmin/script/watchcat.json
|
||||
|
||||
# Check if the script was created successfully
|
||||
if [ -f "$script_path" ]; then
|
||||
# Make the script executable
|
||||
chmod +x "$script_path"
|
||||
|
||||
# Run the script in the background
|
||||
# nohup /bin/sh "$script_path" &
|
||||
/bin/sh "$script_path" &
|
||||
|
||||
echo "Watchcat script created and running."
|
||||
else
|
||||
echo "Failed to create the Watchcat script."
|
||||
echo "Please check the script path: $script_path"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if the script is called with the required parameters
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage: $0 <IP> <timeout> <failure_count>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Call the function with the provided arguments
|
||||
create_and_run_watchcat_script "$1" "$2" "$3"
|
||||
32
old/simpleadmin/script/remove_watchcat.sh
Normal file
32
old/simpleadmin/script/remove_watchcat.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Function to remove the Watchcat script and JSON file
|
||||
remove_watchcat_script() {
|
||||
local script_path="/usrdata/simpleadmin/script/watchcat.sh"
|
||||
local json_path="/usrdata/simpleadmin/script/watchcat.json"
|
||||
|
||||
# Mount as read-write
|
||||
mount -o remount,rw /
|
||||
|
||||
# Remove the watchcat script if it exists
|
||||
if [ -f "$script_path" ]; then
|
||||
rm "$script_path"
|
||||
echo "Removed $script_path"
|
||||
else
|
||||
echo "$script_path does not exist"
|
||||
fi
|
||||
|
||||
# Remove the JSON file if it exists
|
||||
if [ -f "$json_path" ]; then
|
||||
rm "$json_path"
|
||||
echo "Removed $json_path"
|
||||
else
|
||||
echo "$json_path does not exist"
|
||||
fi
|
||||
|
||||
# Mount as read-only
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Call the function to remove the scripts
|
||||
remove_watchcat_script
|
||||
43
old/simpleadmin/script/ttl_script.sh
Normal file
43
old/simpleadmin/script/ttl_script.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check if the required parameters are provided
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <enable|disable> <ttl_value>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign the provided parameters to variables
|
||||
mode="$1"
|
||||
ttl_value="$2"
|
||||
|
||||
# Check if iptables is still set
|
||||
ttlcheck=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}')
|
||||
|
||||
# If TTL is still set, manually remove values
|
||||
if [ ! -z "${ttlcheck}" ]; then
|
||||
/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set "${ttlcheck}" &>/dev/null || true
|
||||
/opt/bin/sudo /usr/sbin/ip6tables -w 5 -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set "${ttlcheck}" &>/dev/null || true
|
||||
fi
|
||||
|
||||
# Handle the enable/disable mode
|
||||
case "${mode}" in
|
||||
enable)
|
||||
# Echo TTL to file
|
||||
echo "${ttl_value}" > /usrdata/simplefirewall/ttlvalue
|
||||
|
||||
# Set Start Service
|
||||
/opt/bin/sudo /usrdata/simplefirewall/ttl-override start
|
||||
;;
|
||||
disable)
|
||||
# Remove TTL value file
|
||||
rm -f /usrdata/simplefirewall/ttlvalue
|
||||
|
||||
# Stop the service
|
||||
/opt/bin/sudo /usrdata/simplefirewall/ttl-override stop
|
||||
;;
|
||||
*)
|
||||
echo "Invalid mode: ${mode}"
|
||||
echo "Usage: $0 <enable|disable> <ttl_value>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
5
old/simpleadmin/simplepasswd
Normal file
5
old/simpleadmin/simplepasswd
Normal file
@@ -0,0 +1,5 @@
|
||||
#/bin/bash
|
||||
|
||||
echo -e "\e[1;31mPlease set your simpleadmin (User: admin) web login password.\e[0m"
|
||||
/usrdata/root/bin/htpasswd -c /opt/etc/.htpasswd admin
|
||||
echo -e "\e[1;32mPassword set.\e[0m"
|
||||
14
old/simpleadmin/systemd/lighttpd.service
Normal file
14
old/simpleadmin/systemd/lighttpd.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Lighttpd Daemon
|
||||
After=network.target opt.mount
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
PIDFile=/opt/var/run/lighttpd.pid
|
||||
ExecStartPre=/opt/sbin/lighttpd -tt -f /usrdata/simpleadmin/lighttpd.conf
|
||||
ExecStart=/opt/sbin/lighttpd -D -f /usrdata/simpleadmin/lighttpd.conf
|
||||
ExecReload=/bin/kill -USR1 $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
old/simpleadmin/systemd/ttyd.service
Normal file
12
old/simpleadmin/systemd/ttyd.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=TTYD Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usrdata/simpleadmin/console/ttyd -i 127.0.0.1 -p 8080 -t 'theme={"foreground":"white","background":"black"}' -t fontSize=25 --writable /usrdata/simpleadmin/console/ttyd.bash
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
35
old/simpleadmin/www/cgi-bin/get_atcommand
Normal file
35
old/simpleadmin/www/cgi-bin/get_atcommand
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [ "$(echo $cmd | grep '=')" ]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$value
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
x=$(urldecode "$atcmd")
|
||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||
if [ -n "${MYATCMD}" ]; then
|
||||
# Initialize wait time to 200 ms
|
||||
wait_time=200
|
||||
while true; do
|
||||
runcmd=$(echo -en "$x\r\n" | microcom -t $wait_time /dev/ttyOUT2)
|
||||
# Check if "OK" or "ERROR" is present in the response
|
||||
if [[ $runcmd =~ "OK" ]] || [[ $runcmd =~ "ERROR" ]]; then
|
||||
break # Exit the loop if "OK" or "ERROR" is found
|
||||
fi
|
||||
# If neither "OK" nor "ERROR" is found, increment wait time by 1 second
|
||||
((wait_time++))
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo $x
|
||||
echo ""
|
||||
echo $runcmd
|
||||
19
old/simpleadmin/www/cgi-bin/get_ping
Normal file
19
old/simpleadmin/www/cgi-bin/get_ping
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will ping 8.8.8.8 and return the result
|
||||
# If the ping is successful, it will return "OK"
|
||||
# If the ping fails, it will return "ERROR"
|
||||
|
||||
# Send the ping command and store the output
|
||||
ping_output=$(ping -c 1 8.8.8.8)
|
||||
|
||||
# Check if the output contains "0% packet loss"
|
||||
if echo "$ping_output" | grep -q "0% packet loss"; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "OK"
|
||||
else
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "ERROR"
|
||||
fi
|
||||
20
old/simpleadmin/www/cgi-bin/get_ttl_status
Normal file
20
old/simpleadmin/www/cgi-bin/get_ttl_status
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check iptables for ttlvalue
|
||||
ttlvalue=$(/opt/bin/sudo /usr/sbin/iptables -w 5 -t mangle -vnL | grep TTL | awk '{print $13}' | head -n1)
|
||||
ttlenabled=true;
|
||||
|
||||
# Set Variables
|
||||
if [ -z "${ttlvalue}" ]; then
|
||||
ttlvalue=0
|
||||
ttlenabled=false
|
||||
fi
|
||||
|
||||
echo "Content-type: text/json"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
{
|
||||
"isEnabled": $ttlenabled,
|
||||
"ttl": $ttlvalue
|
||||
}
|
||||
EOT
|
||||
11
old/simpleadmin/www/cgi-bin/get_uptime
Normal file
11
old/simpleadmin/www/cgi-bin/get_uptime
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Execute the uptime command and store the result
|
||||
uptime_output=$(uptime)
|
||||
|
||||
# Set header for plain text content
|
||||
echo "Content-Type: text/plain"
|
||||
echo ""
|
||||
|
||||
# Output the uptime result
|
||||
echo "$uptime_output"
|
||||
17
old/simpleadmin/www/cgi-bin/get_watchcat_status
Normal file
17
old/simpleadmin/www/cgi-bin/get_watchcat_status
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Content type header
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# This script fetches the watchCat parameters from the /tmp/watchcat.json and returns it as JSON
|
||||
# Example content of /tmp/watchcat:
|
||||
# {"watchcat": {"enabled": true, "track_ip": "1.1.1.1", "ping_timeout": 30, "ping_failure_count": 10}}
|
||||
|
||||
# Check if the file exists
|
||||
if [ -f /tmp/watchcat.json ]; then
|
||||
cat /tmp/watchcat.json
|
||||
else
|
||||
# return an empty JSON object
|
||||
echo "{}"
|
||||
fi
|
||||
31
old/simpleadmin/www/cgi-bin/send_sms
Normal file
31
old/simpleadmin/www/cgi-bin/send_sms
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
urldecode() {
|
||||
local data
|
||||
data="${*//+/ }"
|
||||
echo -e "${data//%/\\x}"
|
||||
}
|
||||
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [[ "$cmd" == *=* ]]; then
|
||||
key=$(echo "$cmd" | awk -F '=' '{print $1}')
|
||||
value=$(echo "$cmd" | awk -F '=' '{print $2}')
|
||||
eval "$key"="$(urldecode "$value")"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
phone_number="$number"
|
||||
message_encoded="$msg"
|
||||
|
||||
|
||||
send_at_command() {
|
||||
local cmd=$1
|
||||
echo -en "$cmd\r" | microcom -t 100 /dev/ttyOUT2
|
||||
}
|
||||
|
||||
send_at_command "AT+CMGS=\"$phone_number\","$Command""
|
||||
runcmd=$((echo -en "$message_encoded"; echo -en "\x1A") | microcom -t 500 /dev/ttyOUT2)
|
||||
echo "$runcmd"
|
||||
64
old/simpleadmin/www/cgi-bin/set_ttl
Normal file
64
old/simpleadmin/www/cgi-bin/set_ttl
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Debug log function
|
||||
log_debug() {
|
||||
local message="$1"
|
||||
debug_logs+=("$message")
|
||||
}
|
||||
|
||||
# Initialize debug logs array
|
||||
declare -a debug_logs=()
|
||||
|
||||
# Get query
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [ "$(echo $cmd | grep '=')" ]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$value
|
||||
log_debug "Received parameter: $key=$value"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
setTTL=$(printf '%b\n' "${ttlvalue//%/\\x}")
|
||||
if [ -n "${setTTL}" ]; then
|
||||
log_debug "Stopping service to remove rules"
|
||||
/usrdata/simplefirewall/ttl-override stop
|
||||
|
||||
# Convert ttlvalue to integer
|
||||
if [ "${ttlvalue}" ]; then
|
||||
ttlvalue_int=$(echo "${ttlvalue}" | sed 's/[^0-9]//g')
|
||||
log_debug "Converted ttlvalue to integer: $ttlvalue_int"
|
||||
fi
|
||||
|
||||
# Call the sh script with the appropriate parameters
|
||||
if [ "${ttlvalue_int}" != 0 ]; then
|
||||
log_debug "Enabling TTL with value: ${setTTL}"
|
||||
/usrdata/simpleadmin/script/ttl_script.sh enable "${setTTL}"
|
||||
commandRan="/usrdata/simpleadmin/script/ttl_script.sh enable ${setTTL}"
|
||||
ttlenabled=true
|
||||
ttlvalue=$ttlvalue_int
|
||||
elif [ "${ttlvalue_int}" = 0 ]; then
|
||||
log_debug "Disabling TTL"
|
||||
/usrdata/simpleadmin/script/ttl_script.sh disable 0
|
||||
commandRan="/usrdata/simpleadmin/script/ttl_script.sh disable 0"
|
||||
ttlenabled=false
|
||||
ttlvalue=0
|
||||
fi
|
||||
|
||||
log_debug "Starting service to apply rules"
|
||||
/usrdata/simplefirewall/ttl-override start
|
||||
fi
|
||||
|
||||
echo "Content-type: text/text"
|
||||
echo ""
|
||||
cat <<EOT
|
||||
{
|
||||
"debug_logs": [
|
||||
$(printf '"%s",' "${debug_logs[@]}")
|
||||
]
|
||||
}
|
||||
EOT
|
||||
125
old/simpleadmin/www/cgi-bin/set_watchcat
Normal file
125
old/simpleadmin/www/cgi-bin/set_watchcat
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [[ "$cmd" == *"="* ]]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$(urldecode $value)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$status" ] || [ -z "$IpDNS" ] || [ -z "$cooldown" ] || [ -z "$failures" ] || [ -z "$action" ]; then
|
||||
response="Missing parameters. Please provide the following parameters: IpDNS, cooldown, failures, action."
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "$response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$status" == "enabled" ]; then
|
||||
watch_script="/usrdata/simpleadmin/script/watchat.sh"
|
||||
mount -o remount,rw /
|
||||
|
||||
cat <<EOF > $watch_script
|
||||
#!/bin/bash
|
||||
|
||||
ip_or_dns="$IpDNS"
|
||||
cooldown=$cooldown
|
||||
action="$action"
|
||||
fail_count=0
|
||||
max_failures=$failures
|
||||
|
||||
# Process the action variable.
|
||||
|
||||
# Create a JSON file containing the parameters of the script
|
||||
echo -n '{"ip_or_dns":"$ip_or_dns","cooldown":$cooldown,"action":"$action","fail_count":$fail_count,"max_failures":$max_failures}' > /tmp/watchatParams.json
|
||||
|
||||
|
||||
while true; do
|
||||
if ping -c 1 -W 1 \$ip_or_dns > /dev/null; then
|
||||
fail_count=0
|
||||
echo "Success at \$(date)" >> /tmp/watchat.log
|
||||
# Convert /tmp/watchat.log to json format
|
||||
echo -n '{"log":[' > /tmp/watchat.json
|
||||
cat /tmp/watchat.log | sed 's/$/,/' | tr -d '\n' | sed 's/,$//' >> /tmp/watchat.json
|
||||
echo -n ']}' >> /tmp/watchat.json
|
||||
else
|
||||
((fail_count++))
|
||||
if [ \$fail_count -ge \$max_failures ]; then
|
||||
case "\$action" in
|
||||
reboot)
|
||||
echo "Rebooting system..."
|
||||
/sbin/reboot
|
||||
;;
|
||||
switch_sim)
|
||||
echo "Switching SIM..."
|
||||
echo -ne "AT+CNMI=2,1\r" > /dev/ttyOUT2
|
||||
sleep 1
|
||||
echo "Switching SIM at \$(date)" >> /tmp/watchat.log
|
||||
;;
|
||||
none)
|
||||
echo "No action taken."
|
||||
echo "No action taken at \$(date)" >> /tmp/watchat.log
|
||||
;;
|
||||
*)
|
||||
echo "Unknown action: \$action"
|
||||
;;
|
||||
esac
|
||||
# Reset fail count
|
||||
fail_count=0
|
||||
fi
|
||||
fi
|
||||
echo "Fail count: \$fail_count at \$(date)" >> /tmp/watchat.log
|
||||
# Convert /tmp/watchat.log to json format
|
||||
echo -n '{"log":[' > /tmp/watchat.json
|
||||
cat /tmp/watchat.log | sed 's/$/,/' | tr -d '\n' | sed 's/,$//' >> /tmp/watchat.json
|
||||
echo -n ']}' >> /tmp/watchat.json
|
||||
sleep \$cooldown
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x $watch_script
|
||||
|
||||
cat <<EOF > /lib/systemd/system/watchcat.service
|
||||
[Unit]
|
||||
Description=Ping Watcher Service
|
||||
|
||||
[Service]
|
||||
ExecStart=$watch_script
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
ln -s /lib/systemd/system/watchcat.service /etc/systemd/system/multi-user.target.wants/watchcat.service
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl start watchcat.service
|
||||
|
||||
response="Script created at $watch_script and made executable. Service created and started."
|
||||
|
||||
elif [ "$status" == "disabled" ]; then
|
||||
watch_script="/usrdata/simpleadmin/script/watchat.sh"
|
||||
rm -f $watch_script
|
||||
|
||||
systemctl stop watchcat.service
|
||||
rm -f /lib/systemd/system/watchcat.service
|
||||
rm -f /etc/systemd/system/multi-user.target.wants/watchcat.service
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
response="Script removed at $watch_script. Service stopped and removed."
|
||||
else
|
||||
response="Invalid status. Please provide either enabled or disabled."
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "$response"
|
||||
26
old/simpleadmin/www/cgi-bin/user_atcommand
Normal file
26
old/simpleadmin/www/cgi-bin/user_atcommand
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [ "$(echo $cmd | grep '=')" ]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$value
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
x=$(urldecode "$atcmd")
|
||||
MYATCMD=$(printf '%b\n' "${atcmd//%/\\x}")
|
||||
if [ -n "${MYATCMD}" ]; then
|
||||
# Capture the response and remove ANSI color codes using awk
|
||||
runcmd=$(atcmd '$x' | awk '{ gsub(/\x1B\[[0-9;]*[mG]/, "") }1')
|
||||
fi
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo $x
|
||||
echo ""
|
||||
echo "$runcmd"
|
||||
72
old/simpleadmin/www/cgi-bin/watchcat_maker
Normal file
72
old/simpleadmin/www/cgi-bin/watchcat_maker
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Decode URL-encoded strings
|
||||
function urldecode() {
|
||||
local data=${1//+/ }
|
||||
printf '%b' "${data//%/\\x}"
|
||||
}
|
||||
|
||||
# Parse QUERY_STRING
|
||||
QUERY_STRING=$(echo "${QUERY_STRING}" | sed 's/;//g')
|
||||
if [ "${QUERY_STRING}" ]; then
|
||||
export IFS="&"
|
||||
for cmd in ${QUERY_STRING}; do
|
||||
if [[ "$cmd" == *"="* ]]; then
|
||||
key=$(echo $cmd | awk -F '=' '{print $1}')
|
||||
value=$(echo $cmd | awk -F '=' '{print $2}')
|
||||
eval $key=$(urldecode $value)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Set default values
|
||||
WATCHCAT_ENABLED=${WATCHCAT_ENABLED:-"disable"}
|
||||
TRACK_IP=${TRACK_IP:-"1.1.1.1"}
|
||||
PING_TIMEOUT=${PING_TIMEOUT:-30}
|
||||
PING_FAILURE_COUNT=${PING_FAILURE_COUNT:-3}
|
||||
|
||||
# Validate input
|
||||
if ! [[ "$WATCHCAT_ENABLED" =~ ^(enable|disable)$ ]]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Invalid value for WATCHCAT_ENABLED. Use 'enable' or 'disable'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$TRACK_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Invalid IP address format for TRACK_IP."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$PING_TIMEOUT" =~ ^[0-9]+$ ]] || [ "$PING_TIMEOUT" -le 0 ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "PING_TIMEOUT must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$PING_FAILURE_COUNT" =~ ^[0-9]+$ ]] || [ "$PING_FAILURE_COUNT" -le 0 ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "PING_FAILURE_COUNT must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Implement the Watchcat logic
|
||||
if [ "$WATCHCAT_ENABLED" == "enable" ]; then
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Watchcat is enabled. Tracking IP: $TRACK_IP, Ping timeout: $PING_TIMEOUT seconds, Ping failure count: $PING_FAILURE_COUNT"
|
||||
# Call the create script here and use the needed parameters
|
||||
sudo /usrdata/simpleadmin/script/create_watchcat.sh "$TRACK_IP" "$PING_TIMEOUT" "$PING_FAILURE_COUNT"
|
||||
else
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Watchcat is disabled."
|
||||
# Call the remove script here
|
||||
sudo /usrdata/simpleadmin/script/remove_watchcat.sh
|
||||
fi
|
||||
|
||||
exit 0
|
||||
6143
old/simpleadmin/www/css/all.min.css
vendored
Normal file
6143
old/simpleadmin/www/css/all.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
old/simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
6
old/simpleadmin/www/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
173
old/simpleadmin/www/css/styles.css
Normal file
173
old/simpleadmin/www/css/styles.css
Normal file
@@ -0,0 +1,173 @@
|
||||
/* import poppins */
|
||||
/* poppins-300 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url('../fonts/poppins-v23-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-300italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: url('../fonts/poppins-v23-latin-300italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-regular - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('../fonts/poppins-v23-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url('../fonts/poppins-v23-latin-italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-500 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('../fonts/poppins-v23-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-500italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
src: url('../fonts/poppins-v23-latin-500italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-600 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url('../fonts/poppins-v23-latin-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-600italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: url('../fonts/poppins-v23-latin-600italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-700 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url('../fonts/poppins-v23-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* poppins-700italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: 'Poppins';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url('../fonts/poppins-v23-latin-700italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* import fontawesome icons */
|
||||
@import url("./all.min.css");
|
||||
|
||||
* {
|
||||
font-family: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
.custom-checkbox .form-check-input {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading-modal {
|
||||
background-color: #fff;
|
||||
padding: 3rem;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border: 3px dotted #000;
|
||||
border-style: solid solid dotted dotted;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 2s linear infinite;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.loader::after {
|
||||
content: "";
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border: 3px dotted #0b5ed7;
|
||||
border-style: solid solid dotted;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
animation: rotationBack 1s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationBack {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.is-warning {
|
||||
background-color: #ffb70f !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.is-medium {
|
||||
font-weight: 600;
|
||||
}
|
||||
522
old/simpleadmin/www/deviceinfo.html
Normal file
522
old/simpleadmin/www/deviceinfo.html
Normal file
@@ -0,0 +1,522 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- <link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="fetchDeviceInfo()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/deviceinfo.html"
|
||||
aria-current="page"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="row mt-5 gap-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Device Information</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Manufacturer</th>
|
||||
<td x-text="manufacturer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Model Name</th>
|
||||
<td x-text="modelName"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Firmware version</th>
|
||||
<td class="col-md-2" x-text="firmwareVersion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Phone Number</th>
|
||||
<td class="col-md-2" x-text="phoneNumber"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IMSI</th>
|
||||
<td class="col-md-2" x-text="imsi"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">ICCID</th>
|
||||
<td class="col-md-2" x-text="iccid"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IMEI</th>
|
||||
<td class="col-md-2">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
x-model="newImei"
|
||||
x-bind:placeholder="imei === '-' ? 'Fetching IMEI...' : imei"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
@click="openModal()"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">LAN IP</th>
|
||||
<td class="col-md-2" x-text="lanIp"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">WWAN IPv<sup>4</sup></th>
|
||||
<td class="col-md-2" x-text="wwanIpv4"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">WWAN IPv<sup>6</sup></th>
|
||||
<td class="col-md-2" x-text="wwanIpv6"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Simple Admin Version</th>
|
||||
<td class="col-md-2">SimpleAdminRev-Alpha-0.9</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Project Contributors</th>
|
||||
<td>
|
||||
<!-- Button trigger modal -->
|
||||
<p
|
||||
type="button"
|
||||
class="link-info link-opacity-50-hover link-offset-2"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#staticBackdrop"
|
||||
>
|
||||
Show Contributors
|
||||
</p>
|
||||
|
||||
<!-- Modal -->
|
||||
<div
|
||||
class="modal fade"
|
||||
id="staticBackdrop"
|
||||
data-bs-backdrop="static"
|
||||
data-bs-keyboard="false"
|
||||
tabindex="-1"
|
||||
aria-labelledby="staticBackdropLabel"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1
|
||||
class="modal-title fs-5"
|
||||
id="staticBackdropLabel"
|
||||
>
|
||||
Contributors
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
RGMII Toolkit and Documentation
|
||||
</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/iamromulan"
|
||||
target="_blank"
|
||||
>iamromulan</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Simple Admin 2.0</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/dr-dolomite"
|
||||
target="_blank"
|
||||
>dr-dolomite</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>SMS Feature</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/snjzb"
|
||||
target="_blank"
|
||||
>snjzb</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Simple Admin</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/aesthernr"
|
||||
target="_blank"
|
||||
>aesthernr</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Socat Bridge</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/natecarlson"
|
||||
target="_blank"
|
||||
>natecarlson</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Original Simple Admin Fixes</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/rbflurry/"
|
||||
target="_blank"
|
||||
>rbflurry</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>SA Parsing Patch</th>
|
||||
<td class="col-md-2">
|
||||
<a
|
||||
href="https://github.com/tarunVreddy"
|
||||
target="_blank"
|
||||
>tarunVreddy</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Visit our
|
||||
<a
|
||||
href="https://github.com/iamromulan/quectel-rgmii-toolkit/tree/development"
|
||||
target="_blank"
|
||||
class="text-reset"
|
||||
>repository</a
|
||||
>
|
||||
or
|
||||
<a
|
||||
href="https://github.com/iamromulan/quectel-rgmii-configuration-notes.git"
|
||||
target="_blank"
|
||||
class="text-reset"
|
||||
>documentation</a
|
||||
>
|
||||
for more information. All rights reserved. 2025
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Modal for Reboot -->
|
||||
<div class="modal-overlay" x-show="showModal">
|
||||
<div class="loading-modal">
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>This will reboot the modem.</h3>
|
||||
<p style="margin-top: 0.5rem">Continue?</p>
|
||||
</div>
|
||||
<div class="d-grid gap-2 d-md-block">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="updateIMEI()"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="closeModal()"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reboot Modal Countdown -->
|
||||
<div class="modal-overlay" x-show="isRebooting">
|
||||
<div class="loading-modal">
|
||||
<div class="loader"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Rebooting...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span>
|
||||
seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function fetchDeviceInfo() {
|
||||
return {
|
||||
manufacturer: "-",
|
||||
modelName: "-",
|
||||
firmwareVersion: "-",
|
||||
imsi: "-",
|
||||
iccid: "-",
|
||||
imei: "-",
|
||||
newImei: null,
|
||||
lanIp: "-",
|
||||
wwanIpv4: "-",
|
||||
wwanIpv6: "-",
|
||||
phoneNumber: "Unknown",
|
||||
simpleAdminVersion: "-",
|
||||
atcmd: null,
|
||||
atCommandResponse: "",
|
||||
showModal: false,
|
||||
isLoading: false,
|
||||
isRebooting: false,
|
||||
countdown: 3,
|
||||
|
||||
sendATCommand() {
|
||||
if (!this.atcmd) {
|
||||
// Use ATI as default command
|
||||
console.log(
|
||||
"AT Command is empty, using ATI as default command: "
|
||||
);
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
fetchATCommand() {
|
||||
this.atcmd =
|
||||
'AT+CGMI;+CGMM;+QGMR;+CIMI;+ICCID;+CGSN;+QMAP="LANIP";+QMAP="WWAN";+CNUM';
|
||||
this.isLoading = true;
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.atcmd,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.parseFetchedData();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
parseFetchedData() {
|
||||
const lines = this.atCommandResponse.split("\n");
|
||||
|
||||
console.log("AT Command Response: ", lines);
|
||||
|
||||
this.manufacturer = lines[1].trim();
|
||||
this.modelName = lines[3].trim();
|
||||
this.firmwareVersion = lines[5].trim();
|
||||
this.imei = lines[11].trim();
|
||||
this.lanIp = lines[13].trim().split(",")[3];
|
||||
this.wwanIpv4 = lines[15].trim().split(",")[4].replace(/"/g, "");
|
||||
this.wwanIpv6 = lines[16].trim().split(",")[4].replace(/"/g, "");
|
||||
|
||||
try {
|
||||
this.imsi = lines[7].trim();
|
||||
this.iccid = lines[9].trim().replace("+ICCID: ", "");
|
||||
this.phoneNumber = lines[18]
|
||||
.trim()
|
||||
.split(",")[1]
|
||||
.replace(/"/g, "");
|
||||
|
||||
if (this.phoneNumber === "") {
|
||||
this.phoneNumber = "Unknown";
|
||||
}
|
||||
} catch (error) {
|
||||
this.phoneNumber = "No SIM Card Inserted or Detected";
|
||||
this.imsi = " ";
|
||||
this.iccid = " ";
|
||||
}
|
||||
|
||||
this.simpleAdminVersion = "SimpleAdminRev-Beta-1.0";
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
updateIMEI() {
|
||||
this.atcmd = `AT+EGMR=1,7,"${this.newImei}"`;
|
||||
this.sendATCommand();
|
||||
this.rebootDevice();
|
||||
},
|
||||
|
||||
rebootDevice() {
|
||||
this.atcmd = "AT+CFUN=1,1";
|
||||
this.sendATCommand();
|
||||
|
||||
this.isLoading = true;
|
||||
this.showModal = false;
|
||||
this.isRebooting = true;
|
||||
this.countdown = 40;
|
||||
const interval = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown === 0) {
|
||||
clearInterval(interval);
|
||||
this.isLoading = false;
|
||||
this.showModal = false;
|
||||
this.isRebooting = false;
|
||||
this.init();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
openModal() {
|
||||
if (!this.newImei) {
|
||||
alert("No new IMEI provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newImei.length !== 15) {
|
||||
alert("IMEI is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newImei === this.imei) {
|
||||
alert("IMEI is the same as the current IMEI");
|
||||
return;
|
||||
}
|
||||
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetchATCommand();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
old/simpleadmin/www/favicon.ico
Normal file
BIN
old/simpleadmin/www/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-300.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-300.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-500.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-500.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-600.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-600.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-700.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-700.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
Normal file
Binary file not shown.
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
Normal file
BIN
old/simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
Normal file
Binary file not shown.
1859
old/simpleadmin/www/index.html
Normal file
1859
old/simpleadmin/www/index.html
Normal file
File diff suppressed because it is too large
Load Diff
5
old/simpleadmin/www/js/alpinejs.min.js
vendored
Normal file
5
old/simpleadmin/www/js/alpinejs.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
old/simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
7
old/simpleadmin/www/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
37
old/simpleadmin/www/js/dark-mode.js
Normal file
37
old/simpleadmin/www/js/dark-mode.js
Normal file
@@ -0,0 +1,37 @@
|
||||
// Function to toggle dark mode
|
||||
const toggleDarkMode = () => {
|
||||
const html = document.querySelector('html');
|
||||
const currentTheme = html.getAttribute('data-bs-theme');
|
||||
|
||||
if (currentTheme === 'dark') {
|
||||
html.removeAttribute('data-bs-theme');
|
||||
darkModeToggle.textContent = 'Dark Mode';
|
||||
localStorage.setItem('theme', 'light'); // Store the theme in localStorage
|
||||
} else {
|
||||
html.setAttribute('data-bs-theme', 'dark');
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
localStorage.setItem('theme', 'dark'); // Store the theme in localStorage
|
||||
}
|
||||
};
|
||||
|
||||
const darkModeToggle = document.getElementById('darkModeToggle');
|
||||
|
||||
// Check if theme preference is stored in localStorage
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
const html = document.querySelector('html');
|
||||
|
||||
if (storedTheme) {
|
||||
html.setAttribute('data-bs-theme', storedTheme);
|
||||
if (storedTheme === 'dark') {
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
} else {
|
||||
darkModeToggle.textContent = 'Dark Mode';
|
||||
}
|
||||
} else {
|
||||
// If no preference is stored, default to dark mode
|
||||
html.setAttribute('data-bs-theme', 'dark');
|
||||
darkModeToggle.textContent = 'Light Mode';
|
||||
localStorage.setItem('theme', 'dark');
|
||||
}
|
||||
|
||||
darkModeToggle.addEventListener('click', toggleDarkMode);
|
||||
37
old/simpleadmin/www/js/generate-freq-box.js
Normal file
37
old/simpleadmin/www/js/generate-freq-box.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const freqNumbersContainer = document.getElementById(
|
||||
"freqNumbersContainer"
|
||||
);
|
||||
|
||||
function generateFreqNumberInputs(num) {
|
||||
let html = "";
|
||||
const maxFields = Math.min(num, 10); // Limit to a maximum of 10 fields
|
||||
for (let i = 1; i <= maxFields; i++) {
|
||||
html += `
|
||||
<div class="input-group mb-3" x-show="cellNum >= ${i} && networkModeCell == 'LTE'">
|
||||
<input
|
||||
type="text"
|
||||
aria-label="EARFCN"
|
||||
placeholder="EARFCN"
|
||||
class="form-control"
|
||||
x-model="earfcn${i}"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
aria-label="PCI"
|
||||
placeholder="PCI"
|
||||
class="form-control"
|
||||
x-model="pci${i}"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const cellNumInput = document.querySelector("[aria-label='NumCells']");
|
||||
cellNumInput.addEventListener("input", function () {
|
||||
const cellNum = parseInt(this.value);
|
||||
freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
|
||||
});
|
||||
});
|
||||
99
old/simpleadmin/www/js/parse-settings.js
Normal file
99
old/simpleadmin/www/js/parse-settings.js
Normal file
@@ -0,0 +1,99 @@
|
||||
function parseCurrentSettings(rawdata) {
|
||||
const data = rawdata;
|
||||
|
||||
const lines = data.split("\n");
|
||||
console.log(lines);
|
||||
|
||||
// Remove QUIMSLOT and only take 1 or 2
|
||||
this.sim = lines
|
||||
.find(
|
||||
(line) => line.includes("QUIMSLOT: 1") || line.includes("QUIMSLOT: 2")
|
||||
)
|
||||
.split(":")[1]
|
||||
// remove spaces
|
||||
.replace(/\s/g, "");
|
||||
// .replace(/\"/g, "");
|
||||
|
||||
try {
|
||||
this.apn = lines
|
||||
.find((line) => line.includes("+CGCONTRDP: 1"))
|
||||
.split(",")[2]
|
||||
.replace(/\"/g, "");
|
||||
} catch (error) {
|
||||
this.apn = "Failed fetching APN";
|
||||
}
|
||||
|
||||
this.cellLock4GStatus = lines
|
||||
.find((line) => line.includes('+QNWLOCK: "common/4g"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.cellLock5GStatus = lines
|
||||
.find((line) => line.includes('+QNWLOCK: "common/5g"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.prefNetwork = lines
|
||||
.find((line) => line.includes('+QNWPREFCFG: "mode_pref"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.nrModeControlStatus = lines
|
||||
.find((line) => line.includes('+QNWPREFCFG: "nr5g_disable_mode"'))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
this.apnIP = lines
|
||||
.find((line) => line.includes("+CGDCONT: 1"))
|
||||
.split(",")[1]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
try {
|
||||
const PCCbands = lines
|
||||
.find((line) => line.includes('+QCAINFO: "PCC"'))
|
||||
.split(",")[3]
|
||||
.replace(/\"/g, "");
|
||||
|
||||
// Loop over all QCAINFO: "SCC" lines and get the bands
|
||||
try {
|
||||
const SCCbands = lines
|
||||
.filter((line) => line.includes('+QCAINFO: "SCC"'))
|
||||
.map((line) => line.split(",")[3].replace(/\"/g, ""))
|
||||
.join(", ");
|
||||
this.bands = `${PCCbands}, ${SCCbands}`;
|
||||
} catch (error) {
|
||||
this.bands = PCCbands;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.bands = "Failed fetching bands";
|
||||
}
|
||||
|
||||
if (this.cellLock4GStatus == 1 && this.cellLock5GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 4G and 5G";
|
||||
} else if (this.cellLock4GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 4G";
|
||||
} else if (this.cellLock5GStatus == 1) {
|
||||
this.cellLockStatus = "Locked to 5G";
|
||||
} else {
|
||||
this.cellLockStatus = "Not Locked";
|
||||
}
|
||||
|
||||
if (this.nrModeControlStatus == 0) {
|
||||
this.nrModeControlStatus = "Not Disabled";
|
||||
} else if (this.nrModeControlStatus == 1) {
|
||||
this.nrModeControlStatus = "SA Disabled";
|
||||
} else {
|
||||
this.nrModeControlStatus = "NSA Disabled";
|
||||
}
|
||||
|
||||
return {
|
||||
sim: sim,
|
||||
apn: apn,
|
||||
apnIP: apnIP,
|
||||
cellLockStatus: cellLockStatus,
|
||||
prefNetwork: prefNetwork,
|
||||
nrModeControl: nrModeControlStatus,
|
||||
bands: bands,
|
||||
};
|
||||
}
|
||||
81
old/simpleadmin/www/js/populate-checkbox.js
Normal file
81
old/simpleadmin/www/js/populate-checkbox.js
Normal file
@@ -0,0 +1,81 @@
|
||||
function populateCheckboxes(lte_band, nsa_nr5g_band, nr5g_band, locked_lte_bands, locked_nsa_bands, locked_sa_bands, cellLock) {
|
||||
var checkboxesForm = document.getElementById("checkboxForm");
|
||||
var selectedMode = document.getElementById("networkModeBand").value;
|
||||
var bands;
|
||||
var prefix;
|
||||
|
||||
// Determine bands and prefix based on selected network mode
|
||||
if (selectedMode === "LTE") {
|
||||
bands = lte_band;
|
||||
prefix = "B";
|
||||
} else if (selectedMode === "NSA") {
|
||||
bands = nsa_nr5g_band;
|
||||
prefix = "N";
|
||||
} else if (selectedMode === "SA") {
|
||||
bands = nr5g_band;
|
||||
prefix = "N";
|
||||
}
|
||||
|
||||
checkboxesForm.innerHTML = ""; // Clear existing checkboxes
|
||||
|
||||
// Store the locked bands in arrays
|
||||
var locked_lte_bands_array = locked_lte_bands.split(":");
|
||||
var locked_nsa_bands_array = locked_nsa_bands.split(":");
|
||||
var locked_sa_bands_array = locked_sa_bands.split(":");
|
||||
|
||||
var isBandLocked = function(band) {
|
||||
if (selectedMode === "LTE" && locked_lte_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
if (selectedMode === "NSA" && locked_nsa_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
if (selectedMode === "SA" && locked_sa_bands_array.includes(band)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
|
||||
if (bands !== null && bands !== "0") {
|
||||
var bandsArray = bands.split(":");
|
||||
var currentRow;
|
||||
|
||||
bandsArray.forEach(function(band, index) {
|
||||
if (index % 5 === 0) {
|
||||
currentRow = document.createElement("div");
|
||||
currentRow.className = "row mb-2 mx-auto"; // Add margin bottom for spacing
|
||||
fragment.appendChild(currentRow);
|
||||
}
|
||||
|
||||
var checkboxDiv = document.createElement("div");
|
||||
checkboxDiv.className = "form-check form-check-reverse col-2"; // Each checkbox takes a column
|
||||
var checkboxInput = document.createElement("input");
|
||||
checkboxInput.className = "form-check-input";
|
||||
checkboxInput.type = "checkbox";
|
||||
checkboxInput.id = "inlineCheckbox" + band;
|
||||
checkboxInput.value = band;
|
||||
checkboxInput.autocomplete = "off";
|
||||
checkboxInput.checked = isBandLocked(band);
|
||||
|
||||
var checkboxLabel = document.createElement("label");
|
||||
checkboxLabel.className = "form-check-label";
|
||||
checkboxLabel.htmlFor = "inlineCheckbox" + band;
|
||||
checkboxLabel.innerText = prefix + band;
|
||||
|
||||
checkboxDiv.appendChild(checkboxInput);
|
||||
checkboxDiv.appendChild(checkboxLabel);
|
||||
currentRow.appendChild(checkboxDiv);
|
||||
});
|
||||
} else {
|
||||
// Create a text saying that no bands are available
|
||||
var noBandsText = document.createElement("p");
|
||||
noBandsText.className = "text-center";
|
||||
noBandsText.innerText = "No supported bands available";
|
||||
fragment.appendChild(noBandsText);
|
||||
}
|
||||
|
||||
checkboxesForm.appendChild(fragment);
|
||||
addCheckboxListeners(cellLock);
|
||||
}
|
||||
1000
old/simpleadmin/www/network.html
Normal file
1000
old/simpleadmin/www/network.html
Normal file
File diff suppressed because it is too large
Load Diff
2393
old/simpleadmin/www/scanner.html
Normal file
2393
old/simpleadmin/www/scanner.html
Normal file
File diff suppressed because it is too large
Load Diff
667
old/simpleadmin/www/settings.html
Normal file
667
old/simpleadmin/www/settings.html
Normal file
@@ -0,0 +1,667 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleSettings()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">AT Terminal</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating mb-4">
|
||||
<!-- At commands output here -->
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="ATI"
|
||||
id="atOutputBox"
|
||||
style="height: 210px"
|
||||
x-text="atCommandResponse"
|
||||
readonly
|
||||
>
|
||||
<label for="floatingTextarea">ATI</label>
|
||||
</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="exampleInputEmail1" class="form-label"
|
||||
>AT Command</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="atCommandInput"
|
||||
placeholder="ATI"
|
||||
aria-describedby="atCommandInput"
|
||||
x-model="atcmd"
|
||||
@keydown.enter="sendATCommand()"
|
||||
/>
|
||||
<div id="atCommandInputHelper" class="form-text">
|
||||
Seperate multiple commands with comma (,).
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-grid gap-2 d-md-flex justify-content-md-start"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary me-md-2"
|
||||
type="button"
|
||||
@click="sendATCommand()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="clearResponses()"
|
||||
:disabled="isClean"
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">One Click Utilities</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Reboot</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="showRebootModal()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Reset AT Commands Settings</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="resetATCommands()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">IP Passthrough</th>
|
||||
<td>
|
||||
<select
|
||||
class="form-select"
|
||||
id="ipPassModeSelect"
|
||||
x-model="ipPassMode"
|
||||
>
|
||||
<option selected>Passthrough Mode</option>
|
||||
<option value="ETH">ETH</option>
|
||||
<option value="USB">USB (ECM/RNDIS)</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="ipPassThroughEnable()"
|
||||
x-show="ipPassStatus === false"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="ipPassThroughDisable()"
|
||||
x-show="ipPassStatus === true"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Disable
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">USB Modem Protocol</th>
|
||||
<td>
|
||||
<select
|
||||
class="form-select"
|
||||
id="usbNetModeSelect"
|
||||
x-model="usbNetMode"
|
||||
>
|
||||
<option
|
||||
selected
|
||||
x-text="currentUsbNetMode"
|
||||
></option>
|
||||
<option value="RMNET">RMNET</option>
|
||||
<option value="ECM">ECM (Recommended)</option>
|
||||
<option value="MBIM">MBIM</option>
|
||||
<option value="RNDIS">RNDIS</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="usbNetModeChanger()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Change
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Onboard DNS Proxy</th>
|
||||
<td>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
@click="onBoardDNSProxyEnable()"
|
||||
x-show="DNSProxyStatus === false"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-danger"
|
||||
@click="onBoardDNSProxyDisable()"
|
||||
x-show="DNSProxyStatus === true"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Disable
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">TTL and Network Scan Settings</div>
|
||||
<div class="card-body">
|
||||
<label for="TTLState" class="form-label"
|
||||
>TTL State and Value</label
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div
|
||||
class="p-3 text-primary-emphasis bg-primary-subtle border border-primary-subtle rounded-3"
|
||||
x-show="ttlStatus === true"
|
||||
>
|
||||
TTL is Active
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="p-3 text-danger-emphasis bg-danger-subtle border border-danger-subtle rounded-3"
|
||||
x-show="ttlStatus === false"
|
||||
>
|
||||
TTL is Inactive
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div
|
||||
class="p-3 text-info-emphasis bg-info-subtle border border-info-subtle rounded-3 mb-4"
|
||||
x-text="ttlvalue"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text mb-3">
|
||||
<div class="mb-4">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ttlInput"
|
||||
placeholder="TTL Value"
|
||||
x-model="newTTL"
|
||||
/>
|
||||
<div id="ttlValueHelper" class="form-text">
|
||||
Set TTL Value to 0 to disable.
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-grid gap-1">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="setTTL()"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="card-text">
|
||||
<div class="d-flex flex-row gap-4 w-full">
|
||||
<p><a class="link-info link-opacity-50-hover link-offset-2" href="/scanner.html">Go to Cell Scanner</a></p>
|
||||
<p><a class="link-info link-opacity-50-hover link-offset-2" href="/watchcat.html">Go to WatchCat</a></p>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Modal for Reboot -->
|
||||
<div class="modal-overlay" x-show="showModal">
|
||||
<div class="loading-modal">
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>This will reboot the modem.</h3>
|
||||
<p style="margin-top: 0.5rem">Continue?</p>
|
||||
</div>
|
||||
<div class="d-grid gap-2 d-md-block">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
@click="rebootDevice()"
|
||||
>
|
||||
Reboot
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
type="button"
|
||||
@click="closeModal()"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reboot Modal Countdown -->
|
||||
<div class="modal-overlay" x-show="isRebooting">
|
||||
<div class="loading-modal">
|
||||
<div class="loader"></div>
|
||||
<div
|
||||
class="loading-text"
|
||||
style="display: flex; flex-direction: column"
|
||||
>
|
||||
<h3>Rebooting...</h3>
|
||||
<p style="margin-top: 0.5rem">
|
||||
Please wait for
|
||||
<span x-text="countdown" style="font-weight: 500"></span>
|
||||
seconds.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleSettings() {
|
||||
return {
|
||||
isLoading: false,
|
||||
showSuccess: false,
|
||||
showError: false,
|
||||
isClean: true,
|
||||
showModal: false,
|
||||
isRebooting: false,
|
||||
atcmd: "",
|
||||
fetchATCommand: "",
|
||||
countdown: 0,
|
||||
atCommandResponse: "",
|
||||
currentSettingsResponse: "",
|
||||
ttldata: null,
|
||||
ttlvalue: 0,
|
||||
ttlStatus: false,
|
||||
newTTL: null,
|
||||
ipPassMode: "Unspecified",
|
||||
ipPassStatus: false,
|
||||
usbNetMode: "Unspecified",
|
||||
currentUsbNetMode: "Unknown",
|
||||
DNSProxyStatus: true,
|
||||
|
||||
closeModal() {
|
||||
this.confirmModal = false;
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
showRebootModal() {
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
sendATCommand() {
|
||||
if (!this.atcmd) {
|
||||
// Use ATI as default command
|
||||
this.atcmd = "ATI";
|
||||
console.log(
|
||||
"AT Command is empty, using ATI as default command: ",
|
||||
this.atcmd
|
||||
);
|
||||
}
|
||||
this.isLoading = true;
|
||||
const encodedATCmd = encodeURIComponent(this.atcmd);
|
||||
const url = `/cgi-bin/get_atcommand?atcmd=${encodedATCmd}`;
|
||||
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLoading = false;
|
||||
this.isClean = false;
|
||||
this.fetchCurrentSettings();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
sendUserATCommand() {
|
||||
this.isLoading = true;
|
||||
const encodedATCmd = encodeURIComponent(this.atcmd);
|
||||
const url = `/cgi-bin/user_atcommand?atcmd=${encodedATCmd}`;
|
||||
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
this.atCommandResponse = data;
|
||||
this.isLoading = false;
|
||||
this.isClean = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
clearResponses() {
|
||||
this.atCommandResponse = "";
|
||||
this.isClean = true;
|
||||
},
|
||||
|
||||
rebootDevice() {
|
||||
this.atcmd = "AT+CFUN=1,1";
|
||||
this.sendATCommand();
|
||||
|
||||
this.atCommandResponse = "";
|
||||
this.showModal = false;
|
||||
this.isRebooting = true;
|
||||
this.countdown = 40;
|
||||
|
||||
// Do the countdown
|
||||
const interval = setInterval(() => {
|
||||
this.countdown--;
|
||||
if (this.countdown === 0) {
|
||||
clearInterval(interval);
|
||||
this.isRebooting = false;
|
||||
this.init();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
resetATCommands() {
|
||||
this.atcmd = "AT&F";
|
||||
this.sendATCommand();
|
||||
console.log("Resetting AT Commands");
|
||||
this.atcmd = "";
|
||||
this.atCommandResponse = "";
|
||||
this.showRebootModal();
|
||||
},
|
||||
|
||||
ipPassThroughEnable() {
|
||||
if (this.ipPassMode != "Unspecified") {
|
||||
if (this.ipPassMode == "ETH") {
|
||||
this.atcmd =
|
||||
// at+qmap="mpdn_rule",0,1,1,1,1,"FF:FF:FF:FF:FF:FF"
|
||||
'AT+QMAP="MPDN_RULE",0,1,0,1,1,"FF:FF:FF:FF:FF:FF"';
|
||||
this.sendATCommand();
|
||||
} else if (this.ipPassMode == "USB") {
|
||||
this.atcmd =
|
||||
'AT+QMAP="MPDN_RULE",0,1,0,3,1,"FF:FF:FF:FF:FF:FF"';
|
||||
this.sendATCommand();
|
||||
} else {
|
||||
console.error("Invalid IP Passthrough Mode");
|
||||
}
|
||||
} else {
|
||||
console.error("IP Passthrough Mode not specified");
|
||||
}
|
||||
},
|
||||
|
||||
ipPassThroughDisable() {
|
||||
this.atcmd = 'AT+QMAP="MPDN_RULE",0;+QMAPWAC=1';
|
||||
this.sendATCommand();
|
||||
},
|
||||
|
||||
onBoardDNSProxyEnable() {
|
||||
this.atcmd = 'AT+QMAP="DHCPV4DNS","enable"';
|
||||
this.sendATCommand().then(() => {
|
||||
this.fetchCurrentSettings();
|
||||
});
|
||||
},
|
||||
|
||||
onBoardDNSProxyDisable() {
|
||||
this.atcmd = 'AT+QMAP="DHCPV4DNS","disable"';
|
||||
this.sendATCommand().then(() => {
|
||||
this.fetchCurrentSettings();
|
||||
});
|
||||
},
|
||||
|
||||
usbNetModeChanger() {
|
||||
if (this.usbNetMode != "Unspecified") {
|
||||
if (this.usbNetMode == "RMNET") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",0;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "ECM") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",1;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "MBIM") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",2;';
|
||||
this.sendATCommand();
|
||||
} else if (this.usbNetMode == "RNDIS") {
|
||||
this.atcmd = 'AT+QCFG="usbnet",3;';
|
||||
this.sendATCommand();
|
||||
} else {
|
||||
console.log("USB Net Mode Invalid");
|
||||
}
|
||||
} else {
|
||||
console.error("USB Net Mode not specified");
|
||||
}
|
||||
this.rebootDevice();
|
||||
},
|
||||
|
||||
fetchCurrentSettings() {
|
||||
this.fetchATCommand =
|
||||
'AT+QMAP="MPDN_RULE";+QMAP="DHCPV4DNS";+QCFG="usbnet"';
|
||||
fetch(
|
||||
"/cgi-bin/get_atcommand?" +
|
||||
new URLSearchParams({
|
||||
atcmd: this.fetchATCommand,
|
||||
})
|
||||
)
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((data) => {
|
||||
// Set the value of currentSettingsResponse
|
||||
this.currentSettingsResponse = data;
|
||||
const currentData = data.split("\n");
|
||||
console.log("Lines: ", currentData);
|
||||
|
||||
const testEthpass = currentData[1].match(
|
||||
/\+QMAP: "MPDN_rule",0,0,0,0,0/
|
||||
);
|
||||
|
||||
if (testEthpass) {
|
||||
this.ipPassStatus = false;
|
||||
} else {
|
||||
this.ipPassStatus = true;
|
||||
}
|
||||
|
||||
const testDNSProxy = currentData[6].match(
|
||||
/\+QMAP: "DHCPV4DNS","enable"/
|
||||
);
|
||||
|
||||
if (testDNSProxy) {
|
||||
this.DNSProxyStatus = true;
|
||||
} else {
|
||||
this.DNSProxyStatus = false;
|
||||
}
|
||||
|
||||
const testUSBNet = currentData[8].match(
|
||||
/\+QCFG: "usbnet",(\d)/
|
||||
);
|
||||
|
||||
if (testUSBNet[1] == "0") {
|
||||
this.currentUsbNetMode = "RMNET";
|
||||
} else if (testUSBNet[1] == "1") {
|
||||
this.currentUsbNetMode = "ECM";
|
||||
} else if (testUSBNet[1] == "2") {
|
||||
this.currentUsbNetMode = "MBIM";
|
||||
} else if (testUSBNet[1] == "3") {
|
||||
this.currentUsbNetMode = "RNDIS";
|
||||
} else {
|
||||
this.currentUsbNetMode = "Unknown";
|
||||
}
|
||||
|
||||
// clear atcmd
|
||||
this.atcmd = "";
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error: ", error);
|
||||
this.showError = true;
|
||||
});
|
||||
},
|
||||
|
||||
fetchTTL() {
|
||||
fetch("/cgi-bin/get_ttl_status")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.ttldata = data;
|
||||
this.ttlStatus = this.ttldata.isEnabled;
|
||||
this.ttlvalue = this.ttldata.ttl;
|
||||
});
|
||||
},
|
||||
|
||||
setTTL() {
|
||||
this.isLoading = true; // Set loading state while updating TTL
|
||||
const ttlval = this.newTTL;
|
||||
fetch(
|
||||
"/cgi-bin/set_ttl?" + new URLSearchParams({ ttlvalue: ttlval })
|
||||
)
|
||||
.then((res) => res.text()) // Use res.text() instead of res.json()
|
||||
.then((data) => {
|
||||
// Manually handle the response data
|
||||
console.log("Response from server:", data);
|
||||
// You can try to parse the JSON manually or handle the response as needed
|
||||
|
||||
// Once TTL is updated, fetch the updated TTL data
|
||||
this.fetchTTL();
|
||||
this.isLoading = false; // Set loading state back to false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error updating TTL: ", error);
|
||||
this.isLoading = false; // Ensure loading state is properly handled in case of error
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.fetchCurrentSettings();
|
||||
this.fetchTTL();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
421
old/simpleadmin/www/sms.html
Normal file
421
old/simpleadmin/www/sms.html
Normal file
@@ -0,0 +1,421 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- 导入自定义和Bootstrap样式 -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
<!-- 网站图标 -->
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
<!-- 导入Bootstrap和Alpine.js脚本 -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<!-- Contributed By: snjzb -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="fetchSMS()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"><span class="mb-0 h4">Simple Admin</span></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarText"
|
||||
aria-controls="navbarText" aria-expanded="false" aria-label="切换导航">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/settings.html">Simple Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html">Device Information</a>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">SMS Inbox</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="col">
|
||||
<div style="
|
||||
max-height: 400px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
">
|
||||
<div x-show="isLoading">
|
||||
<h4>Fetching SMS...</h4>
|
||||
</div>
|
||||
<table class="table table-hover border-success" x-show="!isLoading">
|
||||
<tbody>
|
||||
<!-- 没有消息时显示 -->
|
||||
<!-- Display when there are no messages -->
|
||||
<template x-if="messages.length === 0 && !isLoading">
|
||||
<div>
|
||||
<p>Inbox is Empty</p>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 循环显示短信消息 -->
|
||||
<!-- "Loop display SMS messages" -->
|
||||
<template x-for="(message, index) in messages" :key="index">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" :value="index"
|
||||
x-model="selectedMessages" />
|
||||
<div class="row column-gap-1 mb-2">
|
||||
<div class="col-md-3">
|
||||
<p x-text="'Sender: ' + senders[index]"></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<p x-text="'Date and Time: ' + dates[index]"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<p x-text="message.text"></p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 添加判断,只有当messages数组有内容时才显示全选复选框及其区域 -->
|
||||
<!-- Add a judgment, only when the messages array has content will the select all checkbox and its area be displayed" -->
|
||||
<div class="card-body border-top" x-show="messages.length > 0">
|
||||
<div class="form-check">
|
||||
<input id="selectAllCheckbox" class="form-check-input" type="checkbox" @change="toggleAll($event)" />
|
||||
<label class="form-check-label">Select All</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
|
||||
<!-- 刷新按钮 -->
|
||||
<!-- Refresh button -->
|
||||
<button class="btn btn-success" type="button" @click="init()">
|
||||
Refresh
|
||||
</button>
|
||||
<!-- 删除选中短信按钮 -->
|
||||
<!-- Delete selected SMS button -->
|
||||
<button class="btn btn-danger" type="button" @click="deleteSelectedSMS()">
|
||||
Delete Selected SMS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-5 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Send Message</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label for="phoneNumber" class="form-label">Recipient's Number</label>
|
||||
<input type="text" class="form-control" id="phoneNumber" x-model="phoneNumber"
|
||||
placeholder="Enter the recipient's number." />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="messageToSend" class="form-label">SMS Content</label>
|
||||
<textarea class="form-control" id="messageToSend" rows="3" x-model="messageToSend"
|
||||
placeholder="Enter SMS content."></textarea>
|
||||
</div>
|
||||
<div id="notification" class="alert" style="display: none;"></div>
|
||||
<button class="btn btn-primary" @click="sendSMS()">
|
||||
Send SMS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function fetchSMS() {
|
||||
return {
|
||||
isLoading: false,
|
||||
atCommandResponse: "",
|
||||
messages: [],
|
||||
senders: [],
|
||||
dates: [],
|
||||
selectedMessages: [],
|
||||
phoneNumber: '',
|
||||
messageToSend: '',
|
||||
messageIndices: [], // 确保初始化messageIndices数组
|
||||
|
||||
// 清除现有数据
|
||||
clearData() {
|
||||
this.messages = [];
|
||||
this.senders = [];
|
||||
this.dates = [];
|
||||
this.selectedMessages = [];
|
||||
this.messageIndices = [];
|
||||
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
||||
if (selectAllCheckbox) {
|
||||
selectAllCheckbox.checked = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 请求获取短信
|
||||
requestSMS() {
|
||||
this.isLoading = true;
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: "AT+CSMS=1;+CSDH=0;+CNMI=2,1,0,0,0;+CMGF=1;+CSCA?;+CSMP=17,167,0,8;+CPMS=\"ME\",\"ME\",\"ME\";+CSCS=\"UCS2\";+CMGL=\"ALL\"" })}`)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
this.atCommandResponse = data.split('\n')
|
||||
.filter(line => line.trim() !== "OK" && line.trim() !== "")
|
||||
.join('\n');
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
this.clearData();
|
||||
this.parseSMSData(this.atCommandResponse);
|
||||
});
|
||||
},
|
||||
|
||||
// 解析短信数据的方法
|
||||
parseSMSData(data) {
|
||||
const cmglRegex = /^\s*\+CMGL:\s*(\d+),"[^"]*","([^"]*)"[^"]*,"([^"]*)"/gm;
|
||||
const cscaRegex = /^\s*\+CSCA:\s*"([^"]*)"/gm;
|
||||
this.messageIndices = [];
|
||||
this.serviceCenters = [];
|
||||
this.dates = [];
|
||||
this.senders = [];
|
||||
this.messages = [];
|
||||
let match;
|
||||
let lastIndex = null;
|
||||
while ((match = cmglRegex.exec(data)) !== null) {
|
||||
const index = parseInt(match[1]);
|
||||
const senderHex = match[2];
|
||||
// Maximum world wide phone number length is 17 (North Korea), UTF-16BE Hex string comes back at 48+ for US Number, min length is 3.
|
||||
// When 3 digit SMS short code is used the result is a 12 length string (which we then need to check if the sender hex starts with 003 or 002B(+))
|
||||
// This check is probably completley unecessary but I have no data on how the modems behave with different firmware(whether support for CSCS="UCS2" is available).
|
||||
const sender = senderHex.length > 11 && (senderHex.startsWith('002B') || senderHex.startsWith('003')) ? this.convertHexToText(senderHex) : senderHex;
|
||||
const dateStr = match[3].replace(/\+\d{2}$/, "");
|
||||
const date = this.parseCustomDate(dateStr);
|
||||
if (isNaN(date)) {
|
||||
console.error(`Invalid Date: ${dateStr}`);
|
||||
continue;
|
||||
}
|
||||
const startIndex = cmglRegex.lastIndex;
|
||||
const endIndex = data.indexOf("+CMGL:", startIndex) !== -1 ? data.indexOf("+CMGL:", startIndex) : data.length;
|
||||
const messageHex = data.substring(startIndex, endIndex).trim();
|
||||
const message = /^[0-9a-fA-F]+$/.test(messageHex) ? this.convertHexToText(messageHex) : messageHex;
|
||||
if (lastIndex !== null && this.messages[lastIndex].sender === sender && (date - this.messages[lastIndex].date) / 1000 <= 1) {
|
||||
this.messages[lastIndex].text += " " + message;
|
||||
this.messages[lastIndex].indices.push(index);
|
||||
this.dates[lastIndex] = this.formatDate(date);
|
||||
} else {
|
||||
this.messageIndices.push([index]);
|
||||
this.senders.push(sender);
|
||||
this.dates.push(this.formatDate(date));
|
||||
this.messages.push({ text: message, sender: sender, date: date, indices: [index] });
|
||||
lastIndex = this.messages.length - 1;
|
||||
}
|
||||
}
|
||||
while ((match = cscaRegex.exec(data)) !== null) {
|
||||
const serviceCenterHex = match[1];
|
||||
const serviceCenter = this.convertHexToText(serviceCenterHex);
|
||||
this.serviceCenters.push(serviceCenter);
|
||||
}
|
||||
},
|
||||
|
||||
// 将十六进制转换为文本(假设使用 UTF-16BE 编码)
|
||||
convertHexToText(hex) {
|
||||
const bytes = new Uint8Array(hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
||||
return new TextDecoder('utf-16be').decode(bytes);
|
||||
},
|
||||
|
||||
// 自定义解析日期函数
|
||||
parseCustomDate(dateStr) {
|
||||
const [datePart, timePart] = dateStr.split(',');
|
||||
const [day, month, year] = datePart.split('/').map(part => parseInt(part, 10));
|
||||
const [hour, minute, second] = timePart.split(':').map(part => parseInt(part, 10));
|
||||
|
||||
// 将日期转换为标准格式的日期对象
|
||||
return new Date(Date.UTC(2000 + year, month - 1, day, hour, minute, second));
|
||||
},
|
||||
|
||||
// 自定义格式化日期函数
|
||||
formatDate(date) {
|
||||
const year = date.getUTCFullYear() - 2000;
|
||||
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getUTCDate().toString().padStart(2, '0');
|
||||
const hour = date.getUTCHours().toString().padStart(2, '0');
|
||||
const minute = date.getUTCMinutes().toString().padStart(2, '0');
|
||||
const second = date.getUTCSeconds().toString().padStart(2, '0');
|
||||
return `${day}/${month}/${year},${hour}:${minute}:${second}`;
|
||||
},
|
||||
|
||||
// 删除选中的短信
|
||||
deleteSelectedSMS() {
|
||||
if (this.selectedMessages.length === 0) {
|
||||
console.warn("没有选中的短信");
|
||||
return;
|
||||
}
|
||||
if (!this.messageIndices || this.messageIndices.length === 0) {
|
||||
console.error("短信索引未正确初始化或为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否全选
|
||||
const isAllSelected = this.selectedMessages.length === this.messages.length;
|
||||
|
||||
if (isAllSelected) {
|
||||
// 如果全选,则调用删除所有短信的方法
|
||||
this.deleteAllSMS();
|
||||
} else {
|
||||
// 否则,删除选中的短信
|
||||
const indicesToDelete = [];
|
||||
this.selectedMessages.forEach(index => {
|
||||
indicesToDelete.push(...this.messages[index].indices);
|
||||
});
|
||||
if (indicesToDelete.length === 0) {
|
||||
console.warn("没有有效的短信索引");
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接 AT 命令
|
||||
const atCommands = indicesToDelete.map((index, i) => i === 0 ? `AT+CMGD=${index}` : `+CMGD=${index}`).join(';');
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: atCommands })}`)
|
||||
.finally(() => {
|
||||
this.selectedMessages = [];
|
||||
this.requestSMS();
|
||||
});
|
||||
}
|
||||
},
|
||||
// 删除所有短信
|
||||
deleteAllSMS() {
|
||||
fetch(`/cgi-bin/get_atcommand?${new URLSearchParams({ atcmd: "AT+CMGD=,4" })}`)
|
||||
.finally(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 发送短信
|
||||
encodeUCS2(input) {
|
||||
let output = '';
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const hex = input.charCodeAt(i).toString(16).toUpperCase().padStart(4, '0');
|
||||
output += hex;
|
||||
}
|
||||
return output;
|
||||
},
|
||||
|
||||
async sendSMS() {
|
||||
let phoneNumberWithCountryCode;
|
||||
if (this.phoneNumber.length < 11) {
|
||||
phoneNumberWithCountryCode = this.phoneNumber;
|
||||
} else {
|
||||
const serviceCenterPrefix = this.serviceCenters[0].substring(0, 3);
|
||||
phoneNumberWithCountryCode = `${serviceCenterPrefix}${this.phoneNumber}`;
|
||||
}
|
||||
const encodedPhoneNumber = this.encodeUCS2(phoneNumberWithCountryCode);
|
||||
const messageSegments = this.splitMessage(this.messageToSend, 70); // 将消息分段
|
||||
const uid = Math.floor(Math.random() * 256); // 生成随机的UID
|
||||
const totalSegments = messageSegments.length;
|
||||
let allSegmentsSent = true;
|
||||
let errorCode = null;
|
||||
for (let i = 0; i < totalSegments; i++) {
|
||||
const segment = messageSegments[i];
|
||||
const encodedMessage = this.encodeUCS2(segment);
|
||||
const currentSegment = i + 1;
|
||||
const Command = `${uid},${currentSegment},${totalSegments}`;
|
||||
const params = new URLSearchParams({
|
||||
number: encodedPhoneNumber,
|
||||
msg: encodedMessage,
|
||||
Command: Command
|
||||
});
|
||||
try {
|
||||
const response = await fetch(`/cgi-bin/send_sms?${params.toString()}`);
|
||||
const data = await response.text();
|
||||
console.log("Response from server:", data);
|
||||
|
||||
// 检查返回的数据中是否包含 '+CMS ERROR'
|
||||
if (data.includes('+CMS ERROR')) {
|
||||
errorCode = data.match(/\+CMS ERROR: (\d+)/)?.[1];
|
||||
console.error("SMS send error:", data);
|
||||
allSegmentsSent = false;
|
||||
break; // 停止发送剩余的段
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fetch error:", error);
|
||||
allSegmentsSent = false;
|
||||
break; // 停止发送剩余的段
|
||||
}
|
||||
}
|
||||
if (allSegmentsSent) {
|
||||
this.showNotification("SMS sent successfully!");
|
||||
} else {
|
||||
this.showNotification(`SMS sending failed!: ${errorCode}`);
|
||||
}
|
||||
},
|
||||
|
||||
splitMessage(message, length) {
|
||||
const segments = [];
|
||||
for (let i = 0; i < message.length; i += length) {
|
||||
segments.push(message.substring(i, i + length));
|
||||
}
|
||||
return segments;
|
||||
},
|
||||
|
||||
showNotification(message, type) {
|
||||
const notification = document.getElementById('notification');
|
||||
notification.innerText = message;
|
||||
notification.className = `alert alert-${type}`;
|
||||
notification.style.display = 'block';
|
||||
setTimeout(() => {
|
||||
notification.style.display = 'none';
|
||||
}, 3000); // 3秒后自动关闭
|
||||
},
|
||||
|
||||
// 初始化
|
||||
// Initialize
|
||||
init() {
|
||||
this.clearData();
|
||||
this.requestSMS();
|
||||
},
|
||||
|
||||
// 全选/取消全选
|
||||
// Select all/deselect all
|
||||
toggleAll(event) {
|
||||
this.selectedMessages = event.target.checked ? this.messages.map((_, index) => index) : [];
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
275
old/simpleadmin/www/watchcat.html
Normal file
275
old/simpleadmin/www/watchcat.html
Normal file
@@ -0,0 +1,275 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<style>
|
||||
.form-switch .form-check-input {
|
||||
width: 2.4em;
|
||||
height: 1.2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleWatchCat()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/scanner.html">Simple Scan</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-3 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label> Enable Watchcat </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="watchCatSwitch"
|
||||
x-model="watchCatStatus"
|
||||
:disabled="!isFormComplete"
|
||||
x-on:change="setWatchCatSettings"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Track IP </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Request Timeout </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Failure Amount </label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-4">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Site to Ping"
|
||||
x-model="trackIP"
|
||||
>
|
||||
<option selected>Select IP</option>
|
||||
<option value="1.1.1.1">1.1.1.1</option>
|
||||
<option value="8.8.8.8">8.8.8.8</option>
|
||||
<option value="9.9.9.9">9.9.9.9</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Ping Timeout"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Timeout in Seconds."
|
||||
x-model="pingTimeout"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Sizing example input"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Failure Amount."
|
||||
x-model="pingFailureCount"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Still under development. Coming soon...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat Logs</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating">
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="Leave a comment here"
|
||||
id="floatingTextarea2"
|
||||
style="height: 100px"
|
||||
x-text="response"
|
||||
readonly
|
||||
></textarea>
|
||||
<label for="floatingTextarea2">Logs</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
No log is provided when successfully enabling the watchcat.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleWatchCat() {
|
||||
return {
|
||||
watchCatStatus: false, // Initialize as false (not enabled)
|
||||
trackIP: "",
|
||||
pingTimeout: "",
|
||||
pingFailureCount: "",
|
||||
response: "",
|
||||
|
||||
setWatchCatSettings() {
|
||||
fetch(
|
||||
"/cgi-bin/watchcat_maker?" +
|
||||
new URLSearchParams({
|
||||
WATCHCAT_ENABLED: this.watchCatStatus ? "enable" : "disable",
|
||||
TRACK_IP: this.trackIP,
|
||||
PING_TIMEOUT: this.pingTimeout,
|
||||
PING_FAILURE_COUNT: this.pingFailureCount,
|
||||
})
|
||||
)
|
||||
.then((response) => response.text()) // Convert response to text
|
||||
.then((data) => {
|
||||
this.response = data; // Store the response data
|
||||
console.log(data); // Log the response for debugging
|
||||
})
|
||||
.then(() => {
|
||||
this.fetchWatchCatSettings();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
// Computed property to check if the form is complete
|
||||
get isFormComplete() {
|
||||
return (
|
||||
this.trackIP !== "" &&
|
||||
this.pingTimeout !== "" &&
|
||||
this.pingFailureCount !== ""
|
||||
);
|
||||
},
|
||||
|
||||
// Fetch the current watchcat settings
|
||||
fetchWatchCatSettings() {
|
||||
fetch("/cgi-bin/get_watchcat_status")
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return response.json(); // Parse response as JSON
|
||||
})
|
||||
.then((data) => {
|
||||
console.log(data); // Log the parsed data for debugging
|
||||
|
||||
// Check if the JSON is not empty
|
||||
if (data) {
|
||||
this.watchCatStatus = data.enabled === true;
|
||||
this.trackIP = data.track_ip;
|
||||
this.pingTimeout = data.ping_timeout;
|
||||
this.pingFailureCount = data.ping_failure_count;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetchWatchCatSettings();
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
351
old/simpleadmin/www/watchcat_backup.html
Normal file
351
old/simpleadmin/www/watchcat_backup.html
Normal file
@@ -0,0 +1,351 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Simple Admin</title>
|
||||
<!-- <link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<!-- Import all the bootstrap css files from css folder -->
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
|
||||
<!-- Logo -->
|
||||
<link rel="simpleadmin-logo" href="favicon.ico" />
|
||||
|
||||
<!-- Import BootStrap Javascript -->
|
||||
<script src="js/bootstrap.bundle.min.js"></script>
|
||||
<script src="js/alpinejs.min.js" defer></script>
|
||||
|
||||
<style>
|
||||
.form-switch .form-check-input {
|
||||
width: 2.4em;
|
||||
height: 1.2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container my-4" x-data="simpleWatchCat()">
|
||||
<nav class="navbar navbar-expand-lg mt-2">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/"
|
||||
><span class="mb-0 h4">Simple Admin</span></a
|
||||
>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarText"
|
||||
aria-controls="navbarText"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 ml-4 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/network.html">Simple Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href="/settings.html"
|
||||
aria-current="page"
|
||||
>Simple Settings</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/sms.html">SMS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/console">Console</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/deviceinfo.html"
|
||||
>Device Information</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<button class="btn btn-link text-reset" id="darkModeToggle">
|
||||
Dark Mode
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="row mt-3 mb-4">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label> Enable Watchcat </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="watchCatSwitch"
|
||||
x-model="watchCatStatus"
|
||||
:disabled="!isFormComplete"
|
||||
x:onchange="setWatchCatSettings"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Track IP </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Request Timeout </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Ping Failure Amount </label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-4">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Site to Ping"
|
||||
x-model="trackIP"
|
||||
>
|
||||
<option selected>Select IP</option>
|
||||
<option value="1.1.1.1">1.1.1.1</option>
|
||||
<option value="8.8.8.8">8.8.8.8</option>
|
||||
<option value="9.9.9.9">9.9.9.9</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Ping Timeout"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Timeout in Seconds."
|
||||
x-model="pingTimeout"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="Sizing example input"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Enter Ping Failure Amount."
|
||||
x-model="pingFailureCount"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="row mt-3 mb-5 align-content-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3">
|
||||
<label>Sim Auto Switch</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="mt-2">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="simAutoSwitch"
|
||||
x-model="simAutoSwitchStatus"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="row mt-3 mb-3 align-items-center mx-4">
|
||||
<div class="col">
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Select Preferred SIM </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> SIM 1 APN </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> SIM 2 APN </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Failover Interval </label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-4">
|
||||
<label> Scheduled SIM Hot Swap</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="mt-3 mb-3">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Select Sim"
|
||||
x-model="preferredSim"
|
||||
>
|
||||
<option selected>Select SIM</option>
|
||||
<option value="1">SIM 1</option>
|
||||
<option value="2">SIM 2</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="SIM 1 APN"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Input APN for SIM 1. (Optional)"
|
||||
x-model="sim1APN"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
aria-label="SIM 2 APN"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
placeholder="Input APN for SIM 2. (Optional)"
|
||||
x-model="sim2APN"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3 d-flex align-items-center">
|
||||
<select
|
||||
class="form-select"
|
||||
aria-label="Failover Interval"
|
||||
>
|
||||
<option selected>Failover Interval</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
</select>
|
||||
<label class="mx-3">Minutes</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 mb-3">
|
||||
<input
|
||||
type="time"
|
||||
class="form-control"
|
||||
aria-label="Scheduled SIM Hot Swap"
|
||||
aria-describedby="inputGroup-sizing-default"
|
||||
x-model="scheduledSIMHotSwap"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<!-- Setting a low ping timeout and ping failure count may cause
|
||||
intermittent disconnections due to high sensitivity. <br />
|
||||
Select appropriate values for both based on your needs.<br /> -->
|
||||
Still under development. Coming soon...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">Simple Watchcat Logs</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="form-floating">
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="Leave a comment here"
|
||||
id="floatingTextarea2"
|
||||
style="height: 100px"
|
||||
x-text="response"
|
||||
readonly
|
||||
></textarea>
|
||||
<label for="floatingTextarea2">Logs Here</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="js/dark-mode.js"></script>
|
||||
<script>
|
||||
function simpleWatchCat() {
|
||||
return {
|
||||
watchCatStatus: false,
|
||||
trackIP: "",
|
||||
pingTimeout: "",
|
||||
pingFailureCount: "",
|
||||
response: "",
|
||||
|
||||
setWatchCatSettings() {
|
||||
fetch(
|
||||
"/cgi-bin/watchcat_maker?" +
|
||||
new URLSearchParams({
|
||||
WATCHCAT_ENABLED: this.watchCatStatus,
|
||||
TRACK_IP: this.trackIP,
|
||||
PING_TIMEOUT: this.pingTimeout,
|
||||
PING_FAILURE_COUNT: this.pingFailureCount,
|
||||
})
|
||||
)
|
||||
.then((response) => response.text()) // Convert response to text
|
||||
.then((data) => {
|
||||
this.response = data; // Store the response data
|
||||
console.log(data); // Log the response for debugging
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error); // Handle any errors
|
||||
this.response = "An error occurred.";
|
||||
});
|
||||
},
|
||||
|
||||
// Computed property to check if the form is complete
|
||||
get isFormComplete() {
|
||||
return (
|
||||
this.trackIP !== "" &&
|
||||
this.pingTimeout !== "" &&
|
||||
this.pingFailureCount !== ""
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
old/simplefirewall/.rev
Normal file
1
old/simplefirewall/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
16
old/simplefirewall/simplefirewall.sh
Normal file
16
old/simplefirewall/simplefirewall.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the ports you want to block
|
||||
PORTS=("80" "443") # Default ports, will be modified by the install script
|
||||
|
||||
# First, allow specified ports on bridge0, eth0, and tailscale0
|
||||
for port in "${PORTS[@]}"; do
|
||||
iptables -A INPUT -i bridge0 -p tcp --dport $port -j ACCEPT
|
||||
iptables -A INPUT -i eth0 -p tcp --dport $port -j ACCEPT
|
||||
iptables -A INPUT -i tailscale0 -p tcp --dport $port -j ACCEPT
|
||||
done
|
||||
|
||||
# Then, block specified ports on all other interfaces
|
||||
for port in "${PORTS[@]}"; do
|
||||
iptables -A INPUT -p tcp --dport $port -j DROP
|
||||
done
|
||||
11
old/simplefirewall/systemd/simplefirewall.service
Normal file
11
old/simplefirewall/systemd/simplefirewall.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Simple Firewall Setup
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash /usrdata/simplefirewall/simplefirewall.sh
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
old/simplefirewall/systemd/ttl-override.service
Normal file
12
old/simplefirewall/systemd/ttl-override.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=TTL Override
|
||||
After=ql-netd.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usrdata/simplefirewall/ttl-override start
|
||||
User=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
53
old/simplefirewall/ttl-override
Normal file
53
old/simplefirewall/ttl-override
Normal file
@@ -0,0 +1,53 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Adapted from https://github.com/natecarlson/quectel-rgmii-configuration-notes/blob/main/files/ttl-override
|
||||
# Uses ttlvalue file to read what ttl should be set to
|
||||
|
||||
|
||||
if [ -f /usrdata/simplefirewall/ttlvalue ];
|
||||
then
|
||||
ttlfile=$(</usrdata/simplefirewall/ttlvalue)
|
||||
TTLVALUE=$(echo $ttlfile | grep -o "[0-9]\{1,3\}")
|
||||
|
||||
if [ -z "${TTLVALUE}" ]; then
|
||||
echo "Couldnt get proper ttl value from file" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Couldnt find ttlvalue file, lets generate one with 0 ttlvalue (0 = disabled)
|
||||
touch /usrdata/simplefirewall/ttlvalue && echo '0' > /usrdata/simplefirewall/ttlvalue
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if (( $TTLVALUE > 0 )); then
|
||||
echo "Adding TTL override rules: "
|
||||
iptables -t mangle -I POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE}
|
||||
ip6tables -t mangle -I POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE}
|
||||
else
|
||||
echo "TTLVALUE set to 0, nothing to do..."
|
||||
fi
|
||||
echo "done"
|
||||
;;
|
||||
stop)
|
||||
if (( $TTLVALUE > 0 )); then
|
||||
echo "Removing TTL override rules: "
|
||||
iptables -t mangle -D POSTROUTING -o rmnet+ -j TTL --ttl-set ${TTLVALUE} &>/dev/null || true
|
||||
ip6tables -t mangle -D POSTROUTING -o rmnet+ -j HL --hl-set ${TTLVALUE} &>/dev/null || true
|
||||
else
|
||||
echo "TTLVALUE set to 0, nothing to do..."
|
||||
fi
|
||||
echo "done"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage ttl-override { start | stop | restart }" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
1
old/simplefirewall/ttlvalue
Normal file
1
old/simplefirewall/ttlvalue
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
old/simpleupdates/.rev
Normal file
1
old/simpleupdates/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
271
old/simpleupdates/scripts/update_simpleadmin.sh
Normal file
271
old/simpleupdates/scripts/update_simpleadmin.sh
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simpleadmin"
|
||||
SERVICE_FILE="/lib/systemd/system/install_simpleadmin.service"
|
||||
SERVICE_NAME="install_simpleadmin"
|
||||
TMP_SCRIPT="/tmp/install_simpleadmin.sh"
|
||||
LOG_FILE="/tmp/install_simpleadmin.log"
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Installation Prep
|
||||
remount_rw
|
||||
systemctl daemon-reload
|
||||
rm $SERVICE_FILE > /dev/null 2>&1
|
||||
rm $SERVICE_NAME > /dev/null 2>&1
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SIMPLE_ADMIN_DIR="/usrdata/simpleadmin"
|
||||
export HOME=/usrdata/root
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
uninstall_simpleadmin() {
|
||||
echo "Uninstalling Simpleadmin..."
|
||||
|
||||
# Check if Lighttpd service is installed and remove it if present
|
||||
if [ -f "/lib/systemd/system/lighttpd.service" ]; then
|
||||
echo "Lighttpd detected, uninstalling Lighttpd webserver and its modules..."
|
||||
systemctl stop lighttpd
|
||||
rm -f /lib/systemd/system/lighttpd.service
|
||||
opkg --force-remove --force-removal-of-dependent-packages remove lighttpd-mod-authn_file lighttpd-mod-auth lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy lighttpd
|
||||
fi
|
||||
echo -e "\e[1;34mUninstalling simpleadmin content...\e[0m"
|
||||
systemctl stop simpleadmin_generate_status
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm -f /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm -f /lib/systemd/system/simpleadmin_generate_status.service
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "\e[1;34mUninstalling ttyd...\e[0m"
|
||||
systemctl stop ttyd
|
||||
rm -rf /usrdata/ttyd
|
||||
rm -rf "$SIMPLE_ADMIN_DIR"
|
||||
rm -f /lib/systemd/system/ttyd.service
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/ttyd.service
|
||||
rm -f /bin/ttyd
|
||||
echo -e "\e[1;32mttyd has been uninstalled.\e[0m"
|
||||
|
||||
echo "Uninstallation process completed."
|
||||
}
|
||||
|
||||
install_lighttpd() {
|
||||
# Check for simpleadmin_httpd service and remove if exists
|
||||
if [ -f "/lib/systemd/system/simpleadmin_httpd.service" ]; then
|
||||
systemctl stop simpleadmin_httpd
|
||||
rm /lib/systemd/system/simpleadmin_httpd.service
|
||||
rm /lib/systemd/system/multi-user.target.wants/simpleadmin_httpd.service
|
||||
fi
|
||||
|
||||
/opt/bin/opkg install sudo lighttpd lighttpd-mod-auth lighttpd-mod-authn_file lighttpd-mod-cgi lighttpd-mod-openssl lighttpd-mod-proxy
|
||||
# Ensure rc.unslung doesn't try to start it
|
||||
# Dynamically find and remove any Lighttpd-related init script
|
||||
for script in /opt/etc/init.d/*lighttpd*; do
|
||||
if [ -f "$script" ]; then
|
||||
echo "Removing existing Lighttpd init script: $script"
|
||||
rm "$script" # Remove the script if it contains 'lighttpd' in its name
|
||||
fi
|
||||
done
|
||||
systemctl stop lighttpd
|
||||
echo -e "\033[0;32mInstalling/Updating Lighttpd...\033[0m"
|
||||
mkdir -p "$SIMPLE_ADMIN_DIR"
|
||||
wget -O "$SIMPLE_ADMIN_DIR/lighttpd.conf" $GITROOT/simpleadmin/lighttpd.conf
|
||||
wget -O "/lib/systemd/system/lighttpd.service" $GITROOT/simpleadmin/systemd/lighttpd.service
|
||||
ln -sf "/lib/systemd/system/lighttpd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
echo "www-data ALL = (root) NOPASSWD: /usr/sbin/iptables, /usr/sbin/ip6tables, /usrdata/simplefirewall/ttl-override, /bin/echo, /bin/cat" > /opt/etc/sudoers.d/www-data
|
||||
|
||||
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
|
||||
-subj "/C=US/ST=MI/L=Romulus/O=RMIITools/CN=localhost" \
|
||||
-keyout $SIMPLE_ADMIN_DIR/server.key -out $SIMPLE_ADMIN_DIR/server.crt
|
||||
systemctl daemon-reload
|
||||
systemctl start lighttpd
|
||||
|
||||
echo -e "\033[0;32mLighttpd installation/update complete.\033[0m"
|
||||
}
|
||||
|
||||
install_simpleadmin() {
|
||||
remount_rw
|
||||
echo -e "\e[1;31m2) Installing simpleadmin from the $GITTREE branch\e[0m"
|
||||
mkdir $SIMPLE_ADMIN_DIR
|
||||
mkdir $SIMPLE_ADMIN_DIR/systemd
|
||||
mkdir $SIMPLE_ADMIN_DIR/script
|
||||
mkdir $SIMPLE_ADMIN_DIR/console
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/menu
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/services
|
||||
mkdir $SIMPLE_ADMIN_DIR/console/services/systemd
|
||||
mkdir $SIMPLE_ADMIN_DIR/www
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/cgi-bin
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/css
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/js
|
||||
mkdir $SIMPLE_ADMIN_DIR/www/fonts
|
||||
cd $SIMPLE_ADMIN_DIR/systemd
|
||||
wget $GITROOT/simpleadmin/systemd/lighttpd.service
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/script
|
||||
wget $GITROOT/simpleadmin/script/ttl_script.sh
|
||||
wget $GITROOT/simpleadmin/script/remove_watchcat.sh
|
||||
wget $GITROOT/simpleadmin/script/create_watchcat.sh
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/console
|
||||
wget $GITROOT/simpleadmin/console/.profile
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/console/menu
|
||||
wget $GITROOT/simpleadmin/console/menu/start_menu.sh
|
||||
ln -f $SIMPLE_ADMIN_DIR/console/menu/start_menu.sh /usrdata/root/bin/menu
|
||||
wget $GITROOT/simpleadmin/console/menu/sfirewall_settings.sh
|
||||
wget $GITROOT/simpleadmin/console/menu/start_menu.sh
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www
|
||||
wget $GITROOT/simpleadmin/www/deviceinfo.html
|
||||
wget $GITROOT/simpleadmin/www/favicon.ico
|
||||
wget $GITROOT/simpleadmin/www/index.html
|
||||
wget $GITROOT/simpleadmin/www/network.html
|
||||
wget $GITROOT/simpleadmin/www/settings.html
|
||||
wget $GITROOT/simpleadmin/www/sms.html
|
||||
wget $GITROOT/simpleadmin/www/scanner.html
|
||||
wget $GITROOT/simpleadmin/www/watchcat.html
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/js
|
||||
wget $GITROOT/simpleadmin/www/js/alpinejs.min.js
|
||||
wget $GITROOT/simpleadmin/www/js/bootstrap.bundle.min.js
|
||||
wget $GITROOT/simpleadmin/www/js/dark-mode.js
|
||||
wget $GITROOT/simpleadmin/www/js/generate-freq-box.js
|
||||
wget $GITROOT/simpleadmin/www/js/parse-settings.js
|
||||
wget $GITROOT/simpleadmin/www/js/populate-checkbox.js
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/css
|
||||
wget $GITROOT/simpleadmin/www/css/bootstrap.min.css
|
||||
wget $GITROOT/simpleadmin/www/css/styles.css
|
||||
wget $GITROOT/simpleadmin/www/css/all.min.css
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/fonts
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-300italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-300.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-500italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-500.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-600italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-600.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-700italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-700.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-italic.woff2
|
||||
wget $GITROOT/simpleadmin/www/fonts/poppins-v23-latin-regular.woff2
|
||||
sleep 1
|
||||
cd $SIMPLE_ADMIN_DIR/www/cgi-bin
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_atcommand
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/user_atcommand
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_ping
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_sms
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_ttl_status
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/set_ttl
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/send_sms
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_uptime
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/get_watchcat_status
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/set_watchcat
|
||||
wget $GITROOT/simpleadmin/www/cgi-bin/watchcat_maker
|
||||
sleep 1
|
||||
cd /
|
||||
chmod +x $SIMPLE_ADMIN_DIR/www/cgi-bin/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/script/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/console/menu/*
|
||||
chmod +x $SIMPLE_ADMIN_DIR/console/.profile
|
||||
cp -f $SIMPLE_ADMIN_DIR/console/.profile /usrdata/root/.profile
|
||||
chmod +x /usrdata/root/.profile
|
||||
cp -rf $SIMPLE_ADMIN_DIR/systemd/* /lib/systemd/system
|
||||
sleep 1
|
||||
systemctl daemon-reload
|
||||
sleep 1
|
||||
}
|
||||
install_ttyd() {
|
||||
echo -e "\e[1;34mStarting ttyd installation process...\e[0m"
|
||||
cd $SIMPLE_ADMIN_DIR/console
|
||||
curl -L -o ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.armhf && chmod +x ttyd
|
||||
wget "$GITROOT/simpleadmin/console/ttyd.bash" && chmod +x ttyd.bash
|
||||
cd $SIMPLE_ADMIN_DIR/systemd/
|
||||
wget "$GITROOT/simpleadmin/systemd/ttyd.service"
|
||||
cp -f $SIMPLE_ADMIN_DIR/systemd/ttyd.service /lib/systemd/system/
|
||||
ln -sf /usrdata/simpleadmin/ttyd /bin
|
||||
|
||||
# Enabling and starting ttyd service
|
||||
systemctl daemon-reload
|
||||
ln -sf /lib/systemd/system/ttyd.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl start ttyd
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo -e "\e[1;31mFailed to start ttyd service. Please check the systemd service file and ttyd binary.\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\e[1;32mInstallation Complete! ttyd server is up.\e[0m"
|
||||
}
|
||||
uninstall_simpleadmin
|
||||
install_lighttpd
|
||||
install_simpleadmin
|
||||
install_ttyd
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
124
old/simpleupdates/scripts/update_simplefirewall.sh
Normal file
124
old/simpleupdates/scripts/update_simplefirewall.sh
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simplefirewall"
|
||||
SERVICE_FILE="/lib/systemd/system/install_simplefirewall.service"
|
||||
SERVICE_NAME="install_simplefirewall"
|
||||
TMP_SCRIPT="/tmp/install_simple_firewall.sh"
|
||||
LOG_FILE="/tmp/install_simplefirewall.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SIMPLE_FIREWALL_DIR="/usrdata/simplefirewall"
|
||||
SIMPLE_FIREWALL_SCRIPT="$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
SIMPLE_FIREWALL_SYSTEMD_DIR="$SIMPLE_FIREWALL_DIR/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Function to remove Simple Firewall
|
||||
uninstall_simple_firewall() {
|
||||
echo "Uninstalling Simplefirewall..."
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
rm -f /lib/systemd/system/simplefirewall.service
|
||||
rm -f /lib/systemd/system/ttl-override.service
|
||||
systemctl daemon-reload
|
||||
rm -rf "$SIMPLE_FIREWALL_DIR"
|
||||
echo "Simplefirewall uninstalled."
|
||||
}
|
||||
# Function to install Simple Firewall
|
||||
install_simple_firewall() {
|
||||
systemctl stop simplefirewall
|
||||
systemctl stop ttl-override
|
||||
echo -e "\033[0;32mInstalling/Updating Simple Firewall...\033[0m"
|
||||
mount -o remount,rw /
|
||||
mkdir -p "$SIMPLE_FIREWALL_DIR"
|
||||
mkdir -p "$SIMPLE_FIREWALL_SYSTEMD_DIR"
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/simplefirewall.sh" $GITROOT/simplefirewall/simplefirewall.sh
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttl-override" $GITROOT/simplefirewall/ttl-override
|
||||
wget -O "$SIMPLE_FIREWALL_DIR/ttlvalue" $GITROOT/simplefirewall/ttlvalue
|
||||
chmod 666 $SIMPLE_FIREWALL_DIR/ttlvalue
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/simplefirewall.sh"
|
||||
chmod +x "$SIMPLE_FIREWALL_DIR/ttl-override"
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/simplefirewall.service" $GITROOT/simplefirewall/systemd/simplefirewall.service
|
||||
wget -O "$SIMPLE_FIREWALL_SYSTEMD_DIR/ttl-override.service" $GITROOT/simplefirewall/systemd/ttl-override.service
|
||||
cp -rf $SIMPLE_FIREWALL_SYSTEMD_DIR/* /lib/systemd/system
|
||||
ln -sf "/lib/systemd/system/simplefirewall.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
ln -sf "/lib/systemd/system/ttl-override.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
systemctl daemon-reload
|
||||
systemctl start simplefirewall
|
||||
systemctl start ttl-override
|
||||
echo -e "\033[0;32mSimple Firewall installation/update complete.\033[0m"
|
||||
}
|
||||
uninstall_simple_firewall
|
||||
install_simple_firewall
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
167
old/simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
167
old/simpleupdates/scripts/update_socat-at-bridge.sh
Normal file
@@ -0,0 +1,167 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
DIR_NAME="socat-at-bridge"
|
||||
SERVICE_FILE="/lib/systemd/system/install_socat-at-bridge.service"
|
||||
SERVICE_NAME="install_socat-at-bridge"
|
||||
TMP_SCRIPT="/tmp/install_socat-at-bridge.sh"
|
||||
LOG_FILE="/tmp/install_socat-at-bridge.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
SOCAT_AT_DIR="/usrdata/socat-at-bridge"
|
||||
SOCAT_AT_SYSD_DIR="/usrdata/socat-at-bridge/systemd_units"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
remount_rw
|
||||
uninstall_at_socat() {
|
||||
echo -e "\033[0;32mRemoving installed AT Socat Bridge services...\033[0m"
|
||||
systemctl stop at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl disable at-telnet-daemon > /dev/null 2>&1
|
||||
systemctl stop socat-smd11 > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd11-from-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-to-ttyIN > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN2 > /dev/null 2>&1
|
||||
systemctl stop socat-smd7-from-ttyIN > /dev/null 2>&1
|
||||
rm /lib/systemd/system/at-telnet-daemon.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd11-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN2.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-to-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN.service > /dev/null 2>&1
|
||||
rm /lib/systemd/system/socat-smd7-from-ttyIN2.service > /dev/null 2>&1
|
||||
systemctl daemon-reload > /dev/null 2>&1
|
||||
rm -rf "$SOCAT_AT_DIR" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
install_at_socat() {
|
||||
# Install service units
|
||||
echo -e "\033[0;32mInstalling AT Socat Bridge services...\033[0m"
|
||||
mkdir $SOCAT_AT_DIR
|
||||
cd $SOCAT_AT_DIR
|
||||
mkdir $SOCAT_AT_SYSD_DIR
|
||||
wget $GITROOT/socat-at-bridge/socat-armel-static
|
||||
wget $GITROOT/socat-at-bridge/killsmd7bridge
|
||||
wget $GITROOT/socat-at-bridge/atcmd
|
||||
wget $GITROOT/socat-at-bridge/atcmd11
|
||||
cd $SOCAT_AT_SYSD_DIR
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11-from-ttyIN.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd11-to-ttyIN.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-killsmd7bridge.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7-from-ttyIN2.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7-to-ttyIN2.service
|
||||
wget $GITROOT/socat-at-bridge/systemd_units/socat-smd7.service
|
||||
|
||||
# Set execute permissions
|
||||
cd $SOCAT_AT_DIR
|
||||
chmod +x socat-armel-static
|
||||
chmod +x killsmd7bridge
|
||||
chmod +x atcmd
|
||||
chmod +x atcmd11
|
||||
|
||||
# Link new command for AT Commands from the shell
|
||||
ln -sf $SOCAT_AT_DIR/atcmd /bin
|
||||
ln -sf $SOCAT_AT_DIR/atcmd11 /bin
|
||||
|
||||
# Install service units
|
||||
echo -e "\033[0;32mAdding AT Socat Bridge systemd service units...\033[0m"
|
||||
cp -rf $SOCAT_AT_SYSD_DIR/*.service /lib/systemd/system
|
||||
ln -sf /lib/systemd/system/socat-killsmd7bridge.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-to-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd11-from-ttyIN.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-to-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
ln -sf /lib/systemd/system/socat-smd7-from-ttyIN2.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
systemctl start socat-smd11
|
||||
sleep 2s
|
||||
systemctl start socat-smd11-to-ttyIN
|
||||
systemctl start socat-smd11-from-ttyIN
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd11 to ttyOUT\033[0m"
|
||||
systemctl start socat-killsmd7bridge
|
||||
sleep 1s
|
||||
systemctl start socat-smd7
|
||||
sleep 2s
|
||||
systemctl start socat-smd7-to-ttyIN2
|
||||
systemctl start socat-smd7-from-ttyIN2
|
||||
echo -e "\033[0;32mAT Socat Bridge service online: smd7 to ttyOUT2\033[0m"
|
||||
remount_ro
|
||||
cd /
|
||||
echo -e "\033[0;32mAT Socat Bridge services Installed!\033[0m"
|
||||
}
|
||||
uninstall_at_socat
|
||||
install_at_socat
|
||||
remount_ro
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
90
old/simpleupdates/scripts/update_sshd.sh
Normal file
90
old/simpleupdates/scripts/update_sshd.sh
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
# Define filesystem path
|
||||
DIR_NAME="simpleupdates"
|
||||
SERVICE_FILE="/lib/systemd/system/install_sshd.service"
|
||||
SERVICE_NAME="install_sshd"
|
||||
TMP_SCRIPT="/tmp/install_sshd.sh"
|
||||
LOG_FILE="/tmp/install_sshd.log"
|
||||
|
||||
# Tmp Script dependent constants
|
||||
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
|
||||
|
||||
install_sshd() {
|
||||
echo -e "\e[1;32mOpenSSH Server\e[0m"
|
||||
remount_rw
|
||||
|
||||
mkdir /usrdata/sshd
|
||||
wget -O /lib/systemd/system/sshd.service "$GITROOT/sshd/sshd.service"
|
||||
ln -sf "/lib/systemd/system/sshd.service" "/lib/systemd/system/multi-user.target.wants/"
|
||||
|
||||
opkg install openssh-server-pam
|
||||
for script in /opt/etc/init.d/*sshd*; do
|
||||
if [ -f "$script" ]; then
|
||||
echo "Removing existing sshd init script: $script"
|
||||
rm "$script" # Remove the script if it contains 'sshd' in its name
|
||||
fi
|
||||
done
|
||||
/opt/bin/ssh-keygen -A
|
||||
systemctl daemon-reload
|
||||
systemctl enable sshd
|
||||
|
||||
# Enable PAM and PermitRootLogin
|
||||
sed -i "s/^.*UsePAM .*/UsePAM yes/" "/opt/etc/ssh/sshd_config"
|
||||
sed -i "s/^.*PermitRootLogin .*/PermitRootLogin yes/" "/opt/etc/ssh/sshd_config"
|
||||
|
||||
# Ensure the sshd user exists in the /opt/etc/passwd file
|
||||
grep "sshd:x:106" /opt/etc/passwd || echo "sshd:x:106:65534:Linux User,,,:/opt/run/sshd:/bin/nologin" >> /opt/etc/passwd
|
||||
systemctl start sshd
|
||||
|
||||
echo -e "\e[1;32mOpenSSH installed!!\e[0m"
|
||||
}
|
||||
install_sshd
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
133
old/simpleupdates/scripts/update_tailscale.sh
Normal file
133
old/simpleupdates/scripts/update_tailscale.sh
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define constants
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="development-SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
DIR_NAME="tailscale"
|
||||
SERVICE_FILE="/lib/systemd/system/install_tailscale.service"
|
||||
SERVICE_NAME="install_tailscale"
|
||||
TMP_SCRIPT="/tmp/install_tailscale.sh"
|
||||
LOG_FILE="/tmp/install_tailscale.log"
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
|
||||
# Tmp Script dependent constants
|
||||
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
# Installation Prep
|
||||
remount_rw
|
||||
systemctl daemon-reload
|
||||
rm $SERVICE_FILE > /dev/null 2>&1
|
||||
rm $SERVICE_NAME > /dev/null 2>&1
|
||||
|
||||
# Create the systemd service file
|
||||
cat <<EOF > "$SERVICE_FILE"
|
||||
[Unit]
|
||||
Description=Update $DIR_NAME temporary service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash $TMP_SCRIPT > $LOG_FILE 2>&1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create and populate the temporary shell script for installation
|
||||
cat <<EOF > "$TMP_SCRIPT"
|
||||
#!/bin/bash
|
||||
|
||||
export HOME=/usrdata/root
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/usrdata/root/bin
|
||||
# Define GitHub repo info
|
||||
GITUSER="iamromulan"
|
||||
REPONAME="quectel-rgmii-toolkit"
|
||||
GITTREE="SDXLEMUR"
|
||||
GITMAINTREE="SDXLEMUR"
|
||||
GITDEVTREE="development-SDXLEMUR"
|
||||
GITROOT="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITTREE"
|
||||
GITROOTMAIN="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITMAINTREE"
|
||||
GITROOTDEV="https://raw.githubusercontent.com/$GITUSER/$REPONAME/$GITDEVTREE"
|
||||
# Define filesystem path
|
||||
TAILSCALE_DIR="/usrdata/tailscale/"
|
||||
TAILSCALE_SYSD_DIR="/usrdata/tailscale/systemd"
|
||||
|
||||
# Function to remount file system as read-write
|
||||
remount_rw() {
|
||||
mount -o remount,rw /
|
||||
}
|
||||
|
||||
# Function to remount file system as read-only
|
||||
remount_ro() {
|
||||
mount -o remount,ro /
|
||||
}
|
||||
|
||||
install_update_tailscale() {
|
||||
echo "Checking if Tailscale is already installed..."
|
||||
if [ -f "$TAILSCALE_DIR/tailscale" ]; then
|
||||
echo "Tailscale binary found. Updating Tailscale..."
|
||||
ln -sf "$TAILSCALE_DIR/tailscale" "/usrdata/root/bin/tailscale"
|
||||
echo y | $TAILSCALE_DIR/tailscale update
|
||||
echo -e "\e[32mTailscale updated!\e[0m"
|
||||
remount_ro
|
||||
exit 0
|
||||
else
|
||||
echo "Installing Tailscale..."
|
||||
mkdir -p "$TAILSCALE_DIR" "$TAILSCALE_SYSD_DIR"
|
||||
echo "Downloading binary files..."
|
||||
cd /usrdata
|
||||
curl -O https://pkgs.tailscale.com/stable/tailscale_1.76.1_arm.tgz
|
||||
tar -xzf tailscale_1.76.1_arm.tgz
|
||||
rm tailscale_1.76.1_arm.tgz
|
||||
cd /usrdata/tailscale_1.76.1_arm
|
||||
mv tailscale tailscaled "$TAILSCALE_DIR/"
|
||||
rm -rf /usrdata/tailscale_1.76.1_arm
|
||||
echo "Downloading systemd files..."
|
||||
cd "$TAILSCALE_SYSD_DIR"
|
||||
wget $GITROOT/tailscale/systemd/tailscaled.service
|
||||
wget $GITROOT/tailscale/systemd/tailscaled.defaults
|
||||
sleep 2s
|
||||
echo "Setting Permissions..."
|
||||
chmod +x "$TAILSCALE_DIR/tailscaled" "$TAILSCALE_DIR/tailscale"
|
||||
echo "Copying systemd units..."
|
||||
cp -rf "$TAILSCALE_SYSD_DIR"/* /lib/systemd/system/
|
||||
ln -sf /lib/systemd/system/tailscaled.service /lib/systemd/system/multi-user.target.wants/
|
||||
systemctl daemon-reload
|
||||
echo "Starting Tailscaled..."
|
||||
systemctl start tailscaled
|
||||
cd /
|
||||
ln -sf /usrdata/tailscale/tailscale /usrdata/root/bin
|
||||
remount_ro
|
||||
echo -e "\e[32mTailscale installed successfully.\e[0m"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute the function
|
||||
install_update_tailscale
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Make the temporary script executable
|
||||
chmod +x "$TMP_SCRIPT"
|
||||
|
||||
# Reload systemd to recognize the new service and start the update
|
||||
systemctl daemon-reload
|
||||
systemctl start $SERVICE_NAME
|
||||
12
old/simpleupdates/simpleadmin.conf
Normal file
12
old/simpleupdates/simpleadmin.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
# Enable or disable update checks
|
||||
CONF_ENABLED=no
|
||||
# Check for updates at boot
|
||||
CHECK_AT_BOOT=no
|
||||
# Update frequency: daily, weekly, monthly, or none
|
||||
UPDATE_FREQUENCY=none
|
||||
# Scheduled time for updates (24-hour UTC format)
|
||||
SCHEDULED_TIME=00:00
|
||||
# Day for weekly updates (e.g., Mon, Tues, Wed, Thurs, Fri)
|
||||
WEEKLY_DAY=
|
||||
# Date for monthly updates (e.g., 15 for the 15th of the month)
|
||||
MONTHLY_DATE=
|
||||
255
old/simpleupdates/simpleupdate
Normal file
255
old/simpleupdates/simpleupdate
Normal file
@@ -0,0 +1,255 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration and directories
|
||||
CONFIG_FILE="/usrdata/simpleupdates/simpleupdate.conf"
|
||||
GITUSER="iamromulan"
|
||||
GITTREE="main"
|
||||
DIRECTORIES=("simpleadmin" "socat-at-bridge" "simplefirewall" "tailscale" "ttyd")
|
||||
BASE_URL="https://raw.githubusercontent.com/$GITUSER/quectel-rgmii-toolkit/$GITTREE"
|
||||
LOG_FILE="/tmp/simpleupdate.log"
|
||||
|
||||
# Load configuration
|
||||
load_config() {
|
||||
if [[ -f "$CONFIG_FILE" ]]; then
|
||||
source "$CONFIG_FILE"
|
||||
else
|
||||
echo "Configuration file ($CONFIG_FILE) not found."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to trim the log file to the last 100 lines
|
||||
trim_log_file() {
|
||||
tail -n 100 "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to check for updates
|
||||
check_for_updates() {
|
||||
echo "$(date): Checking for updates..."
|
||||
for dir in "${DIRECTORIES[@]}"; do
|
||||
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||
local local_rev_file="/usrdata/$dir/.rev"
|
||||
|
||||
if [[ ! -f "$local_rev_file" ]]; then
|
||||
echo "No local revision file found for $dir, skipping."
|
||||
continue
|
||||
fi
|
||||
|
||||
local local_rev=$(cat "$local_rev_file")
|
||||
|
||||
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||
echo "Update available for $dir, updating..."
|
||||
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||
chmod +x "/tmp/update_${dir}.sh"
|
||||
"/tmp/update_${dir}.sh"
|
||||
else
|
||||
echo "$dir is up to date."
|
||||
fi
|
||||
done
|
||||
trim_log_file
|
||||
wait_to_update
|
||||
}
|
||||
|
||||
# Function to wait and trigger updates based on scheduling
|
||||
wait_to_update() {
|
||||
echo "Waiting for the next update check according to schedule..."
|
||||
while true; do
|
||||
local current_time=$(date "+%H:%M")
|
||||
local current_day=$(date "+%a")
|
||||
local current_date=$(date "+%d")
|
||||
|
||||
case $UPDATE_FREQUENCY in
|
||||
daily)
|
||||
if [[ "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
weekly)
|
||||
if [[ "$current_day" == "$WEEKLY_DAY" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
monthly)
|
||||
if [[ "$current_date" == "$MONTHLY_DATE" && "$current_time" == "$SCHEDULED_TIME" ]]; then
|
||||
check_for_updates
|
||||
fi
|
||||
;;
|
||||
none)
|
||||
echo "Update checking is disabled by frequency setting."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
sleep 30 # Sleep for 30 seconds for more granular checks
|
||||
trim_log_file
|
||||
done
|
||||
}
|
||||
|
||||
# Daemon mode to wait and trigger updates based on scheduling
|
||||
daemon_mode() {
|
||||
load_config
|
||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||
echo "Daemon mode started."
|
||||
# Validate only one update frequency is defined
|
||||
frequency_count=0
|
||||
[[ "$UPDATE_FREQUENCY" == "daily" ]] && ((frequency_count++))
|
||||
[[ "$UPDATE_FREQUENCY" == "weekly" ]] && ((frequency_count++))
|
||||
[[ "$UPDATE_FREQUENCY" == "monthly" ]] && ((frequency_count++))
|
||||
|
||||
if [[ $frequency_count -gt 1 ]]; then
|
||||
echo "Error: More than one update frequency is defined. Exiting."
|
||||
exit 1
|
||||
elif [[ $frequency_count -eq 0 && "$UPDATE_FREQUENCY" != "none" ]]; then
|
||||
echo "Error: No valid update frequency defined. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$CONF_ENABLED" == "no" ]]; then
|
||||
echo "Updates are disabled in the configuration."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$CHECK_AT_BOOT" == "yes" ]]; then
|
||||
check_for_updates
|
||||
else
|
||||
wait_to_update
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check for updates
|
||||
force_check_for_updates() {
|
||||
echo "$(date): Checking for updates..."
|
||||
for dir in "${DIRECTORIES[@]}"; do
|
||||
local remote_rev=$(wget -qO- "$BASE_URL/$dir/.rev")
|
||||
local local_rev_file="/usrdata/$dir/.rev"
|
||||
|
||||
if [[ ! -f "$local_rev_file" ]]; then
|
||||
echo "No local revision file found for $dir, skipping."
|
||||
continue
|
||||
fi
|
||||
|
||||
local local_rev=$(cat "$local_rev_file")
|
||||
|
||||
if [[ "$remote_rev" -gt "$local_rev" ]]; then
|
||||
echo "Update available for $dir, updating..."
|
||||
wget -qO "/tmp/update_${dir}.sh" "$BASE_URL/simpleupdates/scripts/update_${dir}.sh"
|
||||
chmod +x "/tmp/update_${dir}.sh"
|
||||
"/tmp/update_${dir}.sh"
|
||||
else
|
||||
echo "$dir is up to date."
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Helper function to load and update the configuration
|
||||
update_config() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if grep -q "^$key=" "$CONFIG_FILE"; then
|
||||
sed -i "s|^$key=.*|$key=$value|" "$CONFIG_FILE"
|
||||
else
|
||||
echo "$key=$value" >> "$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Display the current configuration status
|
||||
status() {
|
||||
echo "Current Configuration Status:"
|
||||
if [[ -f "$CONFIG_FILE" ]]; then
|
||||
while IFS= read -r line; do
|
||||
echo "$line"
|
||||
done < "$CONFIG_FILE"
|
||||
else
|
||||
echo "Configuration file not found."
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable automatic updates
|
||||
enable_updates() {
|
||||
update_config "CONF_ENABLED" "yes"
|
||||
echo "Automatic updates have been enabled."
|
||||
}
|
||||
|
||||
# Disable automatic updates
|
||||
disable_updates() {
|
||||
update_config "CONF_ENABLED" "no"
|
||||
echo "Automatic updates have been disabled."
|
||||
}
|
||||
|
||||
# Interactive setup for the update configuration
|
||||
setup() {
|
||||
read -p "Enable automatic updates? [yes/no]: " enable_updates
|
||||
if [[ "$enable_updates" == "yes" ]]; then
|
||||
enable_updates
|
||||
else
|
||||
disable_updates
|
||||
fi
|
||||
|
||||
read -p "Check for updates at boot? [yes/no]: " check_boot
|
||||
update_config "CHECK_AT_BOOT" "$check_boot"
|
||||
|
||||
read -p "Update frequency (none, daily, weekly, monthly): " frequency
|
||||
update_config "UPDATE_FREQUENCY" "$frequency"
|
||||
|
||||
case $frequency in
|
||||
daily)
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
weekly)
|
||||
echo "Please enter the day of the week."
|
||||
read -p "Day (full name or abbreviation, e.g., Monday or Mon): " day_input
|
||||
# Normalize input to abbreviated form
|
||||
day_abbr=$(date -d "$day_input" +%a 2>/dev/null)
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Invalid day of the week. Please try again."
|
||||
return 1
|
||||
fi
|
||||
update_config "WEEKLY_DAY" "$day_abbr"
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
monthly)
|
||||
read -p "Date of the month (1-31): " date
|
||||
update_config "MONTHLY_DATE" "$date"
|
||||
read -p "Scheduled time (HH:MM in 24-hour format): " time
|
||||
update_config "SCHEDULED_TIME" "$time"
|
||||
;;
|
||||
*)
|
||||
echo "No scheduling will be set."
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Update configuration has been set."
|
||||
}
|
||||
|
||||
# Command operations: status, enable, disable, update, setup
|
||||
case "$1" in
|
||||
d)
|
||||
daemon_mode
|
||||
;;
|
||||
update)
|
||||
load_config
|
||||
force_check_for_updates
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
enable)
|
||||
enable_updates
|
||||
;;
|
||||
disable)
|
||||
disable_updates
|
||||
;;
|
||||
setup)
|
||||
setup
|
||||
;;
|
||||
*)
|
||||
echo "Usage:"
|
||||
echo "d: Run as a background check daemon"
|
||||
echo "update: Force check for and install updates"
|
||||
echo "status: Display current set update schedule"
|
||||
echo "enable: Enable automatic updates"
|
||||
echo "disable: Disable automatic updates"
|
||||
echo "setup: Set up an automatic update schedule"
|
||||
;;
|
||||
esac
|
||||
10
old/simpleupdates/systemd/simpleupdated.service
Normal file
10
old/simpleupdates/systemd/simpleupdated.service
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Simple Update Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usrdata/simpleupdates/simpleupdate d
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
1
old/socat-at-bridge/.rev
Normal file
1
old/socat-at-bridge/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
69
old/socat-at-bridge/atcmd
Normal file
69
old/socat-at-bridge/atcmd
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEVICE=/dev/ttyOUT2
|
||||
BAUD=115200
|
||||
|
||||
# Function to setup device communication parameters
|
||||
setup_device() {
|
||||
stty -F $DEVICE cs8 $BAUD ignbrk -brkint -icrnl -imaxbel \
|
||||
-opost -onlcr -isig -icanon -iexten -echo -echoe -echok \
|
||||
-echoctl -echoke noflsh -ixon -crtscts
|
||||
}
|
||||
|
||||
# Function to send AT command and capture the output
|
||||
send_at_command() {
|
||||
local command="$1"
|
||||
|
||||
# Clear the device buffer before sending a new command
|
||||
echo -n > $DEVICE
|
||||
|
||||
# Send the AT command, preserving the integrity of the input
|
||||
echo -e "$command\r" > $DEVICE
|
||||
|
||||
# Use a temporary file to capture the command output
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
# Start reading the device output to the temporary file
|
||||
cat $DEVICE > "$tmpfile" &
|
||||
CAT_PID=$!
|
||||
|
||||
# Monitor the output file for "OK" or "ERROR"
|
||||
while ! grep -qe "OK" -e "ERROR" "$tmpfile"; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Kill the `cat` process after capturing the response
|
||||
kill $CAT_PID
|
||||
wait $CAT_PID 2>/dev/null
|
||||
|
||||
# Display the response
|
||||
cat "$tmpfile" | while IFS= read -r line; do
|
||||
echo -e "\033[0;32m$line\033[0m"
|
||||
done
|
||||
|
||||
# Clean up
|
||||
rm "$tmpfile"
|
||||
}
|
||||
|
||||
# Prepare the device for communication
|
||||
setup_device
|
||||
|
||||
# Check if an AT command is provided as an argument
|
||||
if [ $# -gt 0 ]; then
|
||||
# Concatenate all arguments to handle commands with spaces and/or quotes correctly
|
||||
FULL_CMD="$*"
|
||||
send_at_command "$FULL_CMD"
|
||||
else
|
||||
echo -e "\033[0;36mType 'exit' to end the session.\033[0m"
|
||||
while true; do
|
||||
echo -en "\033[0;36mEnter AT Command: \033[0m"
|
||||
read user_input
|
||||
|
||||
if [[ "$user_input" == "exit" ]]; then
|
||||
echo -e "\033[0;32mExiting...\033[0m"
|
||||
break
|
||||
fi
|
||||
|
||||
send_at_command "$user_input"
|
||||
done
|
||||
fi
|
||||
69
old/socat-at-bridge/atcmd11
Normal file
69
old/socat-at-bridge/atcmd11
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEVICE=/dev/ttyOUT
|
||||
BAUD=115200
|
||||
|
||||
# Function to setup device communication parameters
|
||||
setup_device() {
|
||||
stty -F $DEVICE cs8 $BAUD ignbrk -brkint -icrnl -imaxbel \
|
||||
-opost -onlcr -isig -icanon -iexten -echo -echoe -echok \
|
||||
-echoctl -echoke noflsh -ixon -crtscts
|
||||
}
|
||||
|
||||
# Function to send AT command and capture the output
|
||||
send_at_command() {
|
||||
local command="$1"
|
||||
|
||||
# Clear the device buffer before sending a new command
|
||||
echo -n > $DEVICE
|
||||
|
||||
# Send the AT command, preserving the integrity of the input
|
||||
echo -e "$command\r" > $DEVICE
|
||||
|
||||
# Use a temporary file to capture the command output
|
||||
tmpfile=$(mktemp)
|
||||
|
||||
# Start reading the device output to the temporary file
|
||||
cat $DEVICE > "$tmpfile" &
|
||||
CAT_PID=$!
|
||||
|
||||
# Monitor the output file for "OK" or "ERROR"
|
||||
while ! grep -qe "OK" -e "ERROR" "$tmpfile"; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Kill the `cat` process after capturing the response
|
||||
kill $CAT_PID
|
||||
wait $CAT_PID 2>/dev/null
|
||||
|
||||
# Display the response
|
||||
cat "$tmpfile" | while IFS= read -r line; do
|
||||
echo -e "\033[0;32m$line\033[0m"
|
||||
done
|
||||
|
||||
# Clean up
|
||||
rm "$tmpfile"
|
||||
}
|
||||
|
||||
# Prepare the device for communication
|
||||
setup_device
|
||||
|
||||
# Check if an AT command is provided as an argument
|
||||
if [ $# -gt 0 ]; then
|
||||
# Concatenate all arguments to handle commands with spaces and/or quotes correctly
|
||||
FULL_CMD="$*"
|
||||
send_at_command "$FULL_CMD"
|
||||
else
|
||||
echo -e "\033[0;36mType 'exit' to end the session.\033[0m"
|
||||
while true; do
|
||||
echo -en "\033[0;36mEnter AT Command: \033[0m"
|
||||
read user_input
|
||||
|
||||
if [[ "$user_input" == "exit" ]]; then
|
||||
echo -e "\033[0;32mExiting...\033[0m"
|
||||
break
|
||||
fi
|
||||
|
||||
send_at_command "$user_input"
|
||||
done
|
||||
fi
|
||||
4
old/socat-at-bridge/killsmd7bridge
Normal file
4
old/socat-at-bridge/killsmd7bridge
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Look for the process by its command and kill it so socat can have smd7 instead
|
||||
pkill -f "/usr/bin/port_bridge smd7 at_usb2 1"
|
||||
BIN
old/socat-at-bridge/socat-armel-static
Normal file
BIN
old/socat-at-bridge/socat-armel-static
Normal file
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Kill port_bridge process on boot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usrdata/socat-at-bridge/killsmd7bridge
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/ttyIN and write to smd11
|
||||
BindsTo=socat-smd11.service
|
||||
After=socat-smd11.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/ttyIN > /dev/smd11"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/smd11 and write to ttyIN
|
||||
BindsTo=socat-smd11.service
|
||||
After=socat-smd11.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/smd11 > /dev/ttyIN"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
13
old/socat-at-bridge/systemd_units/socat-smd11.service
Normal file
13
old/socat-at-bridge/systemd_units/socat-smd11.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Socat Serial Emulation for smd11
|
||||
After=ql-netd.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT,raw,echo=1,group=20,perm=660
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/ttyIN2 and write to smd7
|
||||
BindsTo=socat-smd7.service
|
||||
After=socat-smd7.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/ttyIN2 > /dev/smd7"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Read from /dev/smd7 and write to ttyIN2
|
||||
BindsTo=socat-smd7.service
|
||||
After=socat-smd7.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c "/bin/cat /dev/smd7 > /dev/ttyIN2"
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
13
old/socat-at-bridge/systemd_units/socat-smd7.service
Normal file
13
old/socat-at-bridge/systemd_units/socat-smd7.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Socat Serial Emulation for smd7
|
||||
After=ql-netd.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usrdata/socat-at-bridge/socat-armel-static -d -d pty,link=/dev/ttyIN2,raw,echo=0,group=20,perm=660 pty,link=/dev/ttyOUT2,raw,echo=1,group=20,perm=660
|
||||
# Add a delay to prevent the clients from starting too early
|
||||
ExecStartPost=/bin/sleep 2s
|
||||
Restart=always
|
||||
RestartSec=1s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
1
old/sshd/.rev
Normal file
1
old/sshd/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
17
old/sshd/sshd.service
Normal file
17
old/sshd/sshd.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=OpenBSD Secure Shell server
|
||||
Documentation=man:sshd(8) man:sshd_config(5)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
PIDFile=/opt/var/run/sshd.pid
|
||||
ExecStartPre=/opt/sbin/sshd -t
|
||||
ExecStart=/opt/sbin/sshd -D
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=sshd.service
|
||||
1
old/tailscale/.rev
Normal file
1
old/tailscale/.rev
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
8
old/tailscale/systemd/tailscale-webui-trigger.service
Normal file
8
old/tailscale/systemd/tailscale-webui-trigger.service
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Trigger the Tailscale Web UI
|
||||
After=tailscaled.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/systemctl start tailscale-webui
|
||||
RemainAfterExit=yes
|
||||
12
old/tailscale/systemd/tailscale-webui.service
Normal file
12
old/tailscale/systemd/tailscale-webui.service
Normal file
@@ -0,0 +1,12 @@
|
||||
Description=Tailscale Web Interface
|
||||
After=tailscaled.service
|
||||
Requires=tailscaled.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usrdata/tailscale/tailscale web --listen 0.0.0.0:8088
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
8
old/tailscale/systemd/tailscaled.defaults
Normal file
8
old/tailscale/systemd/tailscaled.defaults
Normal file
@@ -0,0 +1,8 @@
|
||||
# Set the port to listen on for incoming VPN packets.
|
||||
# Remote nodes will automatically be informed about the new port number,
|
||||
# but you might want to configure this in order to set external firewall
|
||||
# settings.
|
||||
PORT="41641"
|
||||
|
||||
# Extra flags you might want to pass to tailscaled.
|
||||
FLAGS=""
|
||||
16
old/tailscale/systemd/tailscaled.service
Normal file
16
old/tailscale/systemd/tailscaled.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Tailscale node agent
|
||||
Documentation=https://tailscale.com/kb/
|
||||
Wants=network-pre.target
|
||||
After=network-pre.target NetworkManager.service systemd-resolved.service
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/usrdata/tailscale/systemd/tailscaled.defaults
|
||||
ExecStartPre=/usrdata/tailscale/tailscaled --cleanup
|
||||
ExecStart=/usrdata/tailscale/tailscaled --statedir=/usrdata/tailscale/ --port=${PORT} $FLAGS
|
||||
ExecStopPost=/usrdata/tailscale/tailscaled --cleanup
|
||||
Restart=on-failure
|
||||
Type=notify
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user