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

345 lines
9.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import time
import xmir_base
from gateway import *
cwd = os.path.dirname(os.path.abspath(__file__))
gw = Gateway()
FN_lua = f'tmp/XQFeatures.lua'
fn_lua = '/tmp/XQFeatures.lua'
FN_patch = f'tmp/unlockf_patch.sh'
fn_patch = '/tmp/unlockf_patch.sh'
FN_install = f'tmp/unlockf_install.sh'
fn_install = '/tmp/unlockf_install.sh'
FN_uninstall = f'tmp/unlockf_uninstall.sh'
fn_uninstall = '/tmp/unlockf_uninstall.sh'
os.makedirs('tmp', exist_ok = True)
DEF_FEATURES = {
"system": {
"shutdown": "0",
"downloadlogs": "0",
"i18n": "0",
"infileupload": "1",
"task": "0",
"upnp": "1",
"new_update": "1",
"multiwan": "0", # def: 0 # misc.features.multiwan
"support_1000_dhcp": "1",
"ipv6_wired": "0",
"ipv6_wired_v2": "1",
"plugin_install": "0", # def: 0
"GdprPrivacy": "1",
"international": "1",
"ipv6oversea": "0",
"set_router_location": "0",
"upgraded_light_color": "1",
"change_time": "0", # def: 0
"newRouterPwd": "1",
"https": "1",
"ipv6_passthrough_relay": "1",
"vpn_init": "1",
"mesh_bhtype_mode": "0",
"ipmaccheck": "0",
"map_e": "1",
"dslite": "1",
"map_e_ocn": "1",
},
"wifi": {
"wifi24": "1",
"wifi50": "1",
"wifiguest": "1",
"wifimerge": "1",
"wifi_mu_mimo": "0",
"twt": "1",
"mlo": "1",
"mlo_vap": "1",
"split5g": "0",
"silence_switch": "0",
"wifi_access_ctl": "0", # misc.features.supportWifiAccessCtl # wifiaccess.cfg.enable
"iot_dev": "0", # misc.features.iot_dev
"easymesh_switch": "0",
},
"apmode": {
"wifiapmode": "1", # misc.features.supportWifiAp
"lanapmode": "1",
},
"netmode": {
"elink": "1",
"net2.5G": "0",
"net10G": "0",
},
"apps": {
"apptc": "0",
"qos": "1",
"dhcpMsg": "1",
"upnp": "1",
"nfc": "0",
"wanLan": "1",
"mipctlv2": "0",
"lanPort": "1",
"xqdatacenter": "1",
"baidupan": "0",
"timemachine": "0",
"storage": "0",
"samba": "0",
"docker": "0",
"swapmask": "3", # 0..7
"ports_custom": "1",
"LED_control": "1", # 0..7
"firewall": "0",
"local_gw_security": "0",
"download": "0",
"temp_control": "0",
"sec_center": "0", # 0..2
"sfp": "0",
"game_port": "0", # def: 0 # misc.features.game # misc.wireless.wl_if_count=3
"lan_lag": "1",
"telnet": "0",
},
"hardware": {
"usb": "0",
"usb_deploy": "0",
"disk": "0",
}
}
FEATURES = DEF_FEATURES.copy()
patched_features = { }
def patch_feature(node_name, fname, value, cfg_patch = None):
FEATURES[node_name][fname] = value
pname = f'{node_name}.{fname}'
if pname not in patched_features:
patched_features[pname] = [ ]
if cfg_patch:
patched_features[pname].extend(cfg_patch)
####################################################################################
# Edit me please
patch_feature('system', 'i18n', "1")
patch_feature('system', 'multiwan', "1", [ "misc.features.multiwan=1" ] )
patch_feature('system', 'plugin_install', "1")
patch_feature('system', 'change_time', "1")
patch_feature('wifi', 'wifi_access_ctl', "1", [ "misc.features.supportWifiAccessCtl=1", "wifiaccess.cfg.enable=1" ] )
# patch_feature('apps', 'game_port', "1", [ "misc.features.game=1" ] )
# patch_feature('apps', '__w3__', "1", [ "misc.wireless.wl_if_count=3" ] )
patch_feature('apps', 'baidupan', "1")
#
####################################################################################
lua_table = [ ]
lua_table.append('FEATURES = {')
def parse_feature(depth, elem_dict):
prefix = ' ' * depth if depth >= 1 else ''
for key, elem in elem_dict.items():
if isinstance(elem, dict):
lua_table.append(prefix + f'["{key}"] = ' + '{')
parse_feature(depth + 1, elem)
else:
if isinstance(elem, int) or isinstance(elem, float):
value = f'{elem}'
else:
value = f'"{elem}"'
lua_table.append(prefix + f'["{key}"] = {value},')
if key == list(elem_dict)[-1]:
lua_table.append(prefix + f'["__end__"] = "0"')
prefix_new = ' ' * (depth - 1) if depth >= 2 else ''
lua_table.append(prefix_new + '},')
parse_feature(1, FEATURES)
lua_table[-1] = ' }'
lua_table.append('}')
XQFeatures = '''#!/usr/bin/lua
module "xiaoqiang.XQFeatures"
'''
XQFeatures += '\n' + '\n'.join(lua_table) + '\n'
with open(FN_lua, 'w', newline = '\n') as file:
file.write(XQFeatures)
unlockf_patch = '''#!/bin/sh
INST_FLAG_FN=/tmp/unlockf_patch.log
[ -e "$INST_FLAG_FN" ] && return 0
DIR_PATCH=/etc/crontabs/patches
DIR_BACKUP=$DIR_PATCH/unlockf_backup
TARGET_DIR=/usr/lib/lua/xiaoqiang
MIRROR_DIR=/tmp/_usr_lib_lua_xiaoqiang
SYNCOBJECT=$MIRROR_DIR.sync
if [ ! -f $DIR_PATCH/XQFeatures.lua ; then
return 0
fi
for i in $(seq 1 45); do
mkdir $SYNCOBJECT &> /dev/null && break
sleep 1
done
if ! mount | grep -q " on $TARGET_DIR" ; then
mkdir -p $MIRROR_DIR
cp -rf $TARGET_DIR/* $MIRROR_DIR/
mount --bind $MIRROR_DIR $TARGET_DIR
fi
if [ ! -f $MIRROR_DIR/XQFeatures.lua ]; then
rm -rf $SYNCOBJECT
return 1 # error
fi
# replace XQFeatures.lua
cp -f $DIR_PATCH/XQFeatures.lua $MIRROR_DIR/XQFeatures.lua
rm -rf $SYNCOBJECT
### patch misc config ###
uci set misc.features.xmir_unlockf=1
uci commit misc
echo "unlockf enabled" > /tmp/unlockf_patch.log
'''
misc_patch = ''
for keyname, value in patched_features.items():
vlist = value if isinstance(value, list) else [ value ]
for val in vlist:
if val:
cfg_fn = val.split('.')[0]
misc_patch += f'uci set {val}' + '\n'
misc_patch += f'uci commit {cfg_fn}' + '\n'
unlockf_patch = unlockf_patch.replace('### patch misc config ###', misc_patch)
with open(FN_patch, 'w', newline = '\n') as file:
file.write(unlockf_patch)
unlockf_install = '''#!/bin/sh
INST_FLAG_FN=/tmp/unlockf_patch.log
DIR_PATCH=/etc/crontabs/patches
DIR_BACKUP=$DIR_PATCH/unlockf_backup
TARGET_DIR=/usr/lib/lua/xiaoqiang
MIRROR_DIR=/tmp/_usr_lib_lua_xiaoqiang
SYNCOBJECT=$MIRROR_DIR.sync
if [ ! -f /tmp/XQFeatures.lua ]; then
return 1
fi
if [ ! -d $DIR_PATCH ]; then
mkdir -p $DIR_PATCH
chown root $DIR_PATCH
chmod 0755 $DIR_PATCH
fi
CLEAN_INSTALL=0
if [ ! -d $DIR_BACKUP ]; then
CLEAN_INSTALL=1
mkdir -p $DIR_BACKUP
if [ -f $DIR_BACKUP/misc ]; then
cp -f /etc/config/misc $DIR_BACKUP/misc
fi
fi
if [ $CLEAN_INSTALL = 1 ]; then
NEED_RESTORE_MNT=0
if mount | grep -q " on $TARGET_DIR" ; then
umount -l $TARGET_DIR
NEED_RESTORE_MNT=1
fi
if [ ! -f $DIR_BACKUP/XQFeatures.lua ]; then
cp -f $TARGET_DIR/XQFeatures.lua $DIR_BACKUP/XQFeatures.lua
fi
[ $NEED_RESTORE_MNT = 1 ] && mount --bind $MIRROR_DIR $TARGET_DIR
fi
mv -f /tmp/XQFeatures.lua $DIR_PATCH/
mv -f /tmp/unlockf_patch.sh $DIR_PATCH/
chmod +x $DIR_PATCH/unlockf_patch.sh
uci set firewall.auto_unlockf_patch=include
uci set firewall.auto_unlockf_patch.type='script'
uci set firewall.auto_unlockf_patch.path="$DIR_PATCH/unlockf_patch.sh"
uci set firewall.auto_unlockf_patch.enabled='1'
uci commit firewall
rm -f $INST_FLAG_FN
# run patch
$DIR_PATCH/unlockf_patch.sh
luci-reload
rm -f /tmp/luci-indexcache
luci-reload
'''
with open(FN_install, 'w', newline = '\n') as file:
file.write(unlockf_install)
unlockf_uninstall = '''#!/bin/sh
INST_FLAG_FN=/tmp/unlockf_patch.log
DIR_PATCH=/etc/crontabs/patches
DIR_BACKUP=$DIR_PATCH/unlockf_backup
TARGET_DIR=/usr/lib/lua/xiaoqiang
MIRROR_DIR=/tmp/_usr_lib_lua_xiaoqiang
SYNCOBJECT=$MIRROR_DIR.sync
if [ -d $DIR_BACKUP ]; then
if [ -d $MIRROR_DIR ]; then
cp -f $DIR_BACKUP/XQFeatures.lua $MIRROR_DIR/XQFeatures.lua
fi
cp -f $DIR_BACKUP/misc /etc/config/misc
fi
uci delete firewall.auto_unlockf_patch
uci commit firewall
rm -rf $DIR_BACKUP
rm -f $DIR_PATCH/unlockf_patch.sh
rm -f $DIR_PATCH/XQFeatures.lua
rm -f $INST_FLAG_FN
rm -rf $SYNCOBJECT
luci-reload
rm -f /tmp/luci-indexcache
luci-reload
'''
with open(FN_uninstall, 'w', newline = '\n') as file:
file.write(unlockf_uninstall)
action = 'install'
if len(sys.argv) > 1:
if sys.argv[1].startswith('u') or sys.argv[1].startswith('r'):
action = 'uninstall'
if action == 'install':
gw.upload(FN_lua, fn_lua)
gw.upload(FN_patch, fn_patch)
gw.upload(FN_install, fn_install)
gw.upload(FN_uninstall, fn_uninstall)
print("All files uploaded!")
print("Run scripts...")
run_script = fn_install if action == 'install' else fn_uninstall
gw.run_cmd(f"chmod +x {run_script} ; {run_script}", timeout = 17)
time.sleep(1.5)
gw.run_cmd(f"rm -f {fn_lua} ; rm -f {fn_patch} ; rm -f {fn_install} ; rm -f {fn_uninstall}")
print("Ready! The UnlockFeatures patch installed.")