├── Makefile ├── README.md ├── luasrc ├── controller │ └── scutclient.lua ├── model │ └── cbi │ │ └── scutclient │ │ └── scutclient.lua └── view │ └── scutclient │ ├── about.htm │ ├── logs.htm │ └── status.htm └── root └── etc └── uci-defaults └── 99-luci-scutclient /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 SCUT Router Term 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | include $(TOPDIR)/rules.mk 7 | 8 | LUCI_TITLE:=LuCI Support for scutclient 9 | LUCI_DEPENDS:=+scutclient 10 | PKG_VERSION:=1.3 11 | PKG_RELEASE:=2 12 | PKG_LICENSE:=Apache-2.0 13 | 14 | include ../../luci.mk 15 | 16 | # call BuildPackage - OpenWrt buildroot signature 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # luci-app-scutclient 2 | * 解压放到feeds/luci/applications 3 | * 再执行./scripts/feeds install -a -p luci 4 | * 然后make menuconfig 5 | * 就可以在Luci的Applications看到编译选项 -------------------------------------------------------------------------------- /luasrc/controller/scutclient.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.scutclient", package.seeall) 2 | 3 | http = require "luci.http" 4 | fs = require "nixio.fs" 5 | sys = require "luci.sys" 6 | 7 | log_file = "/tmp/scutclient.log" 8 | log_file_backup = "/tmp/scutclient.log.backup.log" 9 | 10 | function index() 11 | if not fs.access("/etc/config/scutclient") then 12 | return 13 | end 14 | local uci = require "luci.model.uci".cursor() 15 | local mainorder = uci:get_first("scutclient", "luci", "mainorder", 10) 16 | 17 | entry({"admin", "services", "scutclient"}, 18 | alias("admin", "services", "scutclient", "settings"), 19 | "华南理工大学客户端", 20 | mainorder 21 | ) 22 | 23 | entry({"admin", "services", "scutclient", "settings"}, 24 | cbi("scutclient/scutclient"), 25 | "设置", 26 | 10 27 | ).leaf = true 28 | 29 | entry({"admin", "services", "scutclient", "status"}, 30 | call("action_status"), 31 | "状态", 32 | 20 33 | ).leaf = true 34 | 35 | entry({"admin", "services", "scutclient", "logs"}, template("scutclient/logs"), "日志", 30).leaf = true 36 | entry({"admin", "services", "scutclient", "about"}, call("action_about"), "关于", 40).leaf = true 37 | entry({"admin", "services", "scutclient", "get_log"}, call("get_log")) 38 | entry({"admin", "services", "scutclient", "netstat"}, call("get_netstat")) 39 | entry({"admin", "services", "scutclient", "scutclient-log.tar"}, call("get_dbgtar")) 40 | end 41 | 42 | 43 | function get_log() 44 | local send_log_lines = 75 45 | if fs.access(log_file) then 46 | client_log = sys.exec("tail -n "..send_log_lines.." " .. log_file) 47 | else 48 | client_log = "Unable to access the log file!" 49 | end 50 | 51 | http.prepare_content("text/plain; charset=gbk") 52 | http.write(client_log) 53 | http.close() 54 | end 55 | 56 | function action_about() 57 | luci.template.render("scutclient/about") 58 | end 59 | 60 | 61 | function action_status() 62 | luci.template.render("scutclient/status") 63 | if luci.http.formvalue("logoff") == "1" then 64 | luci.sys.call("/etc/init.d/scutclient stop > /dev/null") 65 | end 66 | if luci.http.formvalue("redial") == "1" then 67 | luci.sys.call("/etc/init.d/scutclient stop > /dev/null") 68 | luci.sys.call("/etc/init.d/scutclient start > /dev/null") 69 | end 70 | if luci.http.formvalue("move_tag") == "1" then 71 | luci.sys.call("uci set scutclient.@luci[-1].mainorder=90") 72 | luci.sys.call("uci commit") 73 | luci.sys.call("rm -rf /tmp/luci-*cache") 74 | end 75 | end 76 | 77 | function get_netstat() 78 | local hcontent = sys.exec("wget -O- http://whatismyip.akamai.com 2>/dev/null | head -n1") 79 | local nstat = {} 80 | if hcontent == '' then 81 | nstat.stat = 'no_internet' 82 | elseif hcontent:find("(%d+)%.(%d+)%.(%d+)%.(%d+)") then 83 | nstat.stat = 'internet' 84 | else 85 | nstat.stat = 'no_login' 86 | end 87 | http.prepare_content("application/json") 88 | http.write_json(nstat) 89 | http.close() 90 | end 91 | 92 | function get_dbgtar() 93 | 94 | local tar_dir = "/tmp/scutclient-log" 95 | local tar_files = { 96 | "/etc/config/wireless", 97 | "/etc/config/network", 98 | "/etc/config/system", 99 | "/etc/config/scutclient", 100 | "/etc/openwrt_release", 101 | "/etc/crontabs/root", 102 | "/etc/config/dhcp", 103 | "/tmp/dhcp.leases", 104 | "/etc/rc.local", 105 | } 106 | 107 | fs.mkdirr(tar_dir) 108 | table.foreach(tar_files, function(i, v) 109 | luci.sys.call("cp " .. v .. " " .. tar_dir) 110 | end) 111 | 112 | if fs.access(log_file_backup) then 113 | luci.sys.call("cat " .. log_file_backup .. " >> " .. tar_dir .. "/scutclient.log") 114 | end 115 | if fs.access(log_file) then 116 | luci.sys.call("cat " .. log_file .. " >> " .. tar_dir .. "/scutclient.log") 117 | end 118 | http.prepare_content("application/octet-stream") 119 | http.write(sys.exec("tar -C " .. tar_dir .. " -cf - .")) 120 | luci.sys.call("rm -rf " .. tar_dir) 121 | http.close() 122 | end 123 | -------------------------------------------------------------------------------- /luasrc/model/cbi/scutclient/scutclient.lua: -------------------------------------------------------------------------------- 1 | -- LuCI by libc0607 (libc0607@gmail.com) 2 | -- 华工路由群 262939451 3 | -- 抄的 4 | string.split = function(s, p) 5 | local rt = {} 6 | string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end) 7 | return rt 8 | end 9 | 10 | scut = Map( 11 | "scutclient", 12 | "华南理工大学客户端 设置", 13 | ' ' 18 | ..' ' 23 | ..' ' 28 | ) 29 | function scut.on_commit(self) 30 | luci.sys.call("uci commit") 31 | luci.sys.call("rm -rf /tmp/luci-*cache") 32 | end 33 | 34 | -- config option 35 | scut_option = scut:section(TypedSection, "option", translate("选项")) 36 | scut_option.anonymous = true 37 | 38 | scut_option:option(Flag, "enable", "启用") 39 | 40 | -- config scutclient 41 | scut_client = scut:section(TypedSection, "scutclient", "用户信息") 42 | scut_client.anonymous = true 43 | scut_client:option(Value, "username", "拨号用户名", "学校提供的用户名,一般是学号") 44 | scut_client:option(Value, "password", "拨号密码").password = true 45 | 46 | -- config drcom 47 | scut_drcom = scut:section(TypedSection, "drcom", "Drcom设置") 48 | scut_drcom.anonymous = true 49 | 50 | scut_drcom_version = scut_drcom:option(Value, "version", "Drcom版本") 51 | scut_drcom_version.rmempty = false 52 | scut_drcom_version:value("4472434f4d0096022a") 53 | scut_drcom_version:value("4472434f4d0096022a00636b2031") 54 | scut_drcom_version:value("4472434f4d00cf072a00332e31332e302d32342d67656e65726963") 55 | scut_drcom_version.default = "4472434f4d0096022a" 56 | scut_drcom_hash = scut_drcom:option(Value, "hash", translate("DrAuthSvr.dll版本")) 57 | scut_drcom_hash.rmempty = false 58 | scut_drcom_hash:value("2ec15ad258aee9604b18f2f8114da38db16efd00") 59 | scut_drcom_hash:value("d985f3d51656a15837e00fab41d3013ecfb6313f") 60 | scut_drcom_hash:value("915e3d0281c3a0bdec36d7f9c15e7a16b59c12b8") 61 | scut_drcom_hash.default = "2ec15ad258aee9604b18f2f8114da38db16efd00" 62 | scut_drcom_server = scut_drcom:option(Value, "server_auth_ip", translate("服务器IP")) 63 | scut_drcom_server.rmempty = false 64 | scut_drcom_server.datatype = "ip4addr" 65 | scut_drcom_server:value("202.38.210.131") 66 | scut_drcom_nettime = scut_drcom:option(Value, "nettime", translate("允许上网时间")) 67 | scut_drcom_nettime.description = "允许的上网时间,断网后等待到指定时间重新开始认证。如6:15" 68 | scut_drcom_nettime.validate = function(self, value, t) 69 | if (string.find(value, ":")) then 70 | local sp = string.split(value, ":") 71 | 72 | if (#sp == 2) then 73 | local hour, minute = tonumber(sp[1]), tonumber(sp[2]) 74 | if (hour and minute and hour >= 0 and hour < 12 and minute >= 0 and minute < 60) then 75 | return value 76 | end 77 | end 78 | end 79 | 80 | return nil, "上网时间格式错误!" 81 | end 82 | 83 | --[[ 主机名列表预置 84 | 1.生成一个 DESKTOP-XXXXXXX 的随机 85 | 2.dhcp分配的第一个 86 | ]]-- 87 | scut_drcom_hostname = scut_drcom:option(Value, "hostname", translate("向服务器发送的主机名")) 88 | scut_drcom_hostname.rmempty = false 89 | 90 | local random_hostname = "DESKTOP-" 91 | local randtmp 92 | 93 | math.randomseed(os.time()) 94 | for i = 1, 7 do 95 | randtmp = math.random(1, 36) 96 | random_hostname = (randtmp > 10) 97 | and random_hostname..string.char(randtmp+54) 98 | or random_hostname..string.char(randtmp+47) 99 | end 100 | 101 | -- 获取dhcp列表,加入第一个主机名候选 102 | local dhcp_hostnames = string.split(luci.sys.exec("cat /tmp/dhcp.leases|awk {'print $4'}"), "\n") or {} 103 | 104 | scut_drcom_hostname:value(random_hostname) 105 | scut_drcom_hostname:value(dhcp_hostnames[1]) 106 | scut_drcom_hostname.default = random_hostname 107 | 108 | return scut 109 | -------------------------------------------------------------------------------- /luasrc/view/scutclient/about.htm: -------------------------------------------------------------------------------- 1 | <%+header%> 2 | 3 |

4 | 许可证 5 |

6 | 7 |

8 | AGPLv3 9 |

10 |

特别指出禁止任何个人或组织将scutclient的代码投入商业使用,由此造成的后果和法律责任后果自负。

11 | 12 | 13 |

14 | 致谢 15 |

16 |

群主的猫
ฅ(⌯͒• ɪ •⌯͒)ฅ❣

17 |
18 | 19 |

20 | 华工路由器群官方微博
21 | QQ审核群:262939451 22 |

23 | 24 | <%+footer%> 25 | -------------------------------------------------------------------------------- /luasrc/view/scutclient/logs.htm: -------------------------------------------------------------------------------- 1 | <%+header%> 2 | 3 |

4 | 客户端日志 5 |

6 | 7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
配置文件")'>
17 | 18 |

19 | scutclient日志 20 |

21 | 22 |
23 | 26 |
27 | 28 | 44 | 45 | <%+footer%> 46 | -------------------------------------------------------------------------------- /luasrc/view/scutclient/status.htm: -------------------------------------------------------------------------------- 1 | <% 2 | -- LuCI by libc0607 (libc0607@gmail.com) 3 | -- 华工路由群:262939451 4 | 5 | local sys = require "luci.sys" 6 | local fs = require "nixio.fs" 7 | local uci = require "luci.model.uci".cursor() 8 | local ntm = require "luci.model.network".init() 9 | local scutclient_version = luci.sys.exec("opkg list-installed scutclient | cut -d ' ' -f 3") 10 | local scutclient_status = {} 11 | scutclient_status.enable = uci:get_first("scutclient", "option", "enable") 12 | scutclient_status.username = uci:get_first("scutclient", "scutclient", "username") 13 | scutclient_status.password = uci:get_first("scutclient", "scutclient", "password") 14 | scutclient_status.hostname = uci:get_first("scutclient", "drcom", "hostname") 15 | scutclient_status.version = uci:get_first("scutclient", "drcom", "version") 16 | scutclient_status.hash = uci:get_first("scutclient", "drcom", "hash") 17 | scutclient_status.server_auth_ip = uci:get_first("scutclient", "drcom", "server_auth_ip") 18 | local mode_links = {} 19 | mode_links.base = luci.dispatcher.build_url("admin/services/scutclient/status") 20 | mode_links.redial = mode_links.base.."?redial=1" 21 | mode_links.logoff = mode_links.base.."?logoff=1" 22 | mode_links.move_tag = mode_links.base .."?move_tag=1" 23 | 24 | local stat, wan_nets = pcall(ntm.get_wan_networks, ntm) 25 | local wan, wandev 26 | if stat then 27 | if #wan_nets > 0 then 28 | wan = wan_nets[1] 29 | wandev = wan:get_interface() 30 | end 31 | else 32 | wan = ntm:get_wannet() 33 | wandev = ntm:get_wandev() 34 | end 35 | 36 | function get_client_status(exec_name) 37 | return (os.execute("pidof scutclient > /dev/null 2>/dev/null") == 0) 38 | end 39 | 40 | function get_wifi_switch() 41 | return (string.sub(luci.sys.exec("wifi status|grep up|head -n 1|awk {'print $2'}"), 1, 4) == "true") 42 | and true 43 | or false 44 | end 45 | 46 | %> 47 | 48 | 49 | <%+header%> 50 | 51 |

52 | 客户端状态 53 |

54 |
55 | 56 | 状态 57 | 58 | 59 |
60 | 61 | 62 | 63 | 64 | 65 | <% if get_client_status("scutclient") then %> 66 | 67 | <% else %> 68 | 69 | <% end %> 70 | 71 | 72 | 73 | <% if get_wifi_switch() then -%> 74 | 75 | 76 | <% else %> 77 | 78 | 79 | <% end %> 80 | 81 | 82 | <% if wan then %> 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | <% else %> 117 | 118 | 119 | 120 | <% end %> 121 | 122 | 123 |
scutclient正在运行没有运行
Wi-Fi SSID :<%=luci.sys.exec("uci get wireless.@wifi-iface[0].ssid")%>Wi-Fi 状态:未开启,或路由器没有无线网卡
WAN口<%=wandev:name()%>
IP地址<%=wan:ipaddr()%>
子网掩码<%=wan:netmask()%>
网关<%=wan:gwaddr()%>
DNS<%=table.concat(wan:dnsaddrs(), ",")%>
MAC<%=wandev:mac()%>
网络状态获取中……
WAN口未正确配置
124 |
125 | 126 | 127 | 128 | 129 |
130 | 131 | 客户端设置 132 | 133 | 134 |
135 | 136 | 137 | 138 | 139 | 140 | 144 | 145 | 146 | 147 | <% if string.len(scutclient_version) > 1 then %> 148 | 149 | 150 | <% else %> 151 | 152 | <% end %> 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | <% if scutclient_status.username == "root" then %> 163 | 164 | <% else %> 165 | 166 | <% end %> 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 |
功能 141 | 下线 142 | 重拨 143 |
已安装版本:<%=scutclient_version%>scutclient未安装
开机启动<%=scutclient_status.enable%>
账号<%=scutclient_status.username%>。。。你的浏览器开启了自动保存帐号密码?<%=scutclient_status.username%>
密码<%=scutclient_status.password%>
主机名<%=scutclient_status.hostname%>
Drcom版本<%=scutclient_status.version%>
Hash<%=scutclient_status.hash%>
服务器IP<%=scutclient_status.server_auth_ip%>
196 |
197 | 198 | 199 | 200 | 201 | 283 | <%+footer%> 284 | -------------------------------------------------------------------------------- /root/etc/uci-defaults/99-luci-scutclient: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete ucitrack.@scutclient[-1] 5 | add ucitrack scutclient 6 | set ucitrack.@scutclient[-1].init=scutclient 7 | commit ucitrack 8 | delete scutclient.@luci[-1] 9 | add scutclient luci 10 | commit scutclient 11 | EOF 12 | rm -f /tmp/luci-indexcache 13 | /etc/init.d/scutclient enable 14 | exit 0 15 | --------------------------------------------------------------------------------