说明

以luci-app-njitclient客户端学习luci新增页面


代码结构

package
├── helloworld
├── luci-app-njitclient-master
│   ├── files
│   │   └── root
│   │       ├── etc
│   │       │   ├── config
│   │       │   │   └── njitclient
│   │       │   └── init.d
│   │       │       └── njitclient
│   │       └── usr
│   │           └── lib
│   │               └── lua
│   │                   └── luci
│   │                       ├── controller
│   │                       │   └── njitclient.lua
│   │                       └── model
│   │                           └── cbi
│   │                               └── njitclient.lua
│   ├── LICENSE
│   ├── Makefile
│   └── README.md
└── Makefile

代码

package/luci-app-njitclient-master/Makefile
include $(TOPDIR)/rules.mk

## 软件包名称,将在menuconfig和ipkg可以看到
PKG_NAME:=luci-app-njitclient
## 软件版本号
PKG_VERSION=1.0
## Makefile的版本号
PKG_RELEASE:=1
## 软件维护者
PKG_MAINTAINER:=JPH 
## 源代码的文件名
# PKG_SOURCE
## 源代码的下载网站位置
# PKG_SOURCE_URL
# 获取代码方式可以为git、svn、cvs、hg、bzr等
# 下载方法参考$(INCLUDE_DIR)/download.mk 和 $(SCRIPT_DIR)/download.pl
#   @SF     sourceforge网站
#   @GNU    GNU网站
#   @GNOME
#   @KERNEL
## 源代码文件的效验码
# PKG_MD5SUM
## 源代码文件的解压方法
# PKG_CAT

## 软件包编译目录 [默认为$(BUILD_DIR)/$( PKG_NAME)$( PKG_VERSION)]
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

## 编译包 定义
define Package/$(PKG_NAME)
    # 包的类型
    SECTION:=luci
    # 分类, 在menuconfig的菜单下将可以找到
    CATEGORY:=LuCI
    # 子分类 对应menuconfig中/LuCI/3. Applications/luci-app-njitclient
    SUBMENU:=3. Applications
    # 软件包的简短描述
    TITLE:=NJIT 802.1X Client for LuCI
    # control中的 Architecture 字段, 默认为当前编译器的交叉编译环境平台
    PKGARCH:=all
    # URL               软件包的下载地址
    # MAINTAINER        维护者
    # DEPENDS           与其他软件的依赖, 即如编译或安装需要其他软件时需要说明 DEPENDS:=+libmath +libzlib
endef

## 软件包的详细描述, control中的 Description 字段, 默认为TITLE
define Package/$(PKG_NAME)/description
    This package contains LuCI configuration pages for njit8021xclient.
endef

## 编译准备 创建文件夹、拷贝源文件
define Build/Prepare
endef

## 针对需要配置的软件包 Automake中./configure
define Build/Configure
endef

## 编译方法 没特殊说明不定义 使用默认编译方法
# $(MAKE) -C $(PKG_BUILD_DIR) \
#   $(TARGET_CONFIGURE_OPTS) CFLAGS="$(TARGET_CFLAGS) -I$(LINUX_DIR)/include"
define Build/Compile
endef

## 软件包的安装方法     $(1) -> 嵌入系统的镜像目录 /
define Package/$(PKG_NAME)/install
    $(INSTALL_DIR) $(1)/etc/config
    $(INSTALL_DIR) $(1)/etc/init.d
    $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi
    $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
    
    $(INSTALL_CONF) ./files/root/etc/config/njitclient $(1)/etc/config/njitclient
    $(INSTALL_BIN) ./files/root/etc/init.d/njitclient $(1)/etc/init.d/njitclient
    $(INSTALL_DATA) ./files/root/usr/lib/lua/luci/model/cbi/njitclient.lua $(1)/usr/lib/lua/luci/model/cbi/njitclient.lua
    $(INSTALL_DATA) ./files/root/usr/lib/lua/luci/controller/njitclient.lua $(1)/usr/lib/lua/luci/controller/njitclient.lua
endef

## 软件包安装前处理方法, 使用脚本语言
define Package/$(PKG_NAME)/preinst
    #!/bin/sh
    echo "###$(PKG_MAINTAINER): To install $(PKG_NAME)"
endef

## 软件包安装后处理方法, 使用脚本语言
define Package/$(PKG_NAME)/postinst
    #!/bin/sh
    echo "###$(PKG_MAINTAINER): $(PKG_NAME) install succeed"
endef

## 软件包删除前处理方法, 使用脚本语言
define Package/$(PKG_NAME)/prerm
    #!/bin/sh
    echo "###$(PKG_MAINTAINER): To remove $(PKG_NAME)"
endef

## 软件包删除后处理方法, 使用脚本语言
define Package/$(PKG_NAME)/postrm
    #!/bin/sh
    echo "###$(PKG_MAINTAINER): $(PKG_NAME) remove succeed"
endef

## 使用eval函数实现各种定义
$(eval $(call BuildPackage,$(PKG_NAME))
package/luci-app-njitclient-master/files/root/usr/lua/luci/controller/njitclient.lua
--[[ 模块入口 ]]

-- 程序模块名    /usr/lib/lua/luci/controller/njitclient.lua
module("luci.controller.njitclient", package.seeall)

function index()
    -- 添加一个新的模块(Page)入口
    -- entry(路径, 调用目标, _("显示名称"), 显示顺序)
    -- 路径 以字符串数组给定 {"admin", "network", "njitclient"} -> http://ip/cgi-bin/luci/admin/network/njitclient
    -- 调用目标:
        -- 执行指定方法(Action):call("function_name")
        -- 访问指定页面(Views):template("myapp/mymodule") 访问/usr/lib/lua/luci/view/myapp/mymodule.htm
        -- 调用CBI(Configuration Binding Interface) Module:cbi("myapp/mymodule")  调用/usr/lib/lua/luci/model/cbi/myapp/mymodule.lua
        -- 重定向:alias("admin", "status", "overview")
    entry({"admin", "network", "njitclient"}, cbi("njitclient"), _("NJIT Client"), 100)
    end
package/luci-app-njitclient-master/files/root/usr/lua/luci/model/cbi/njitclient.lua
--[[ 配置模块实际的代码 ]]

require("luci.sys")

-- 映射与存储文件的关系
-- m = Map("配置文件文件名", "配置页面标题", "配置页面说明")
    -- 配置文件文件名:配置文件存储的文件名,不包含路径 /etc/config/xxx
m = Map("njitclient", translate("NJIT Client"), translate("Configure NJIT 802.11x client."))

-- 配置文件中对应的section
s = m:section(TypedSection, "login", "")
-- 不允许增加或删除
s.addremove = false
-- 不显示Section的名称
s.anonymous = true

-- 配置文件中section的交互(创建Option)
    -- Value(文本框)
    -- ListValue(下拉框)
    -- Flag(选择框)
enable = s:option(Flag, "enable", translate("Enable"))
name = s:option(Value, "username", translate("Username"))
pass = s:option(Value, "password", translate("Password"))
pass.password = true
domain = s:option(Value, "domain", translate("Domain"))

ifname = s:option(ListValue, "ifname", translate("Interfaces"))
for k, v in ipairs(luci.sys.net.devices()) do
    if v ~= "lo" then
        ifname:value(v)
    end
end

-- 判断是否点击了“应用”按钮
local apply = luci.http.formvalue("cbi.apply")
if apply then
    io.popen("/etc/init.d/njitclient restart")
end

return m
package/luci-app-njitclient-master/files/root/etc/init.d/njitclient
#!/bin/sh /etc/rc.common
START=50

run_njit()
{
    local enable
    # 获取变量值
    # config_get_bool 变量名 Section名 Section参数名
    config_get_bool enable $1 enable
    
    if [ $enable ]; then
        local username
        local password
        local domain
        local ifname
        
        # 获取变量值
        # config_get 变量名 Section名 Section参数名
        config_get username $1 username
        config_get password $1 password
        config_get domain $1 domain
        config_get ifname $1 ifname
        
        if [ "$domain" != "" ]; then
            njit-client $username@$domain $password $ifname &
        else
            njit-client $username $password $ifname &
        fi
        
        echo "NJIT Client has started."
    fi
}

start()
{
    # 读取配置文件
    config_load njitclient
    
    # 遍历配置文件中的Section
    # config_foreach 遍历函数名 Section类型
    config_foreach run_njit login
}

stop()
{
    killall njit-client
    killall udhcpc
    
    echo "NJIT Client has stoped."
}
package/luci-app-njitclient-master/files/root/etc/init.d/njitclient
config login
    option username ''
    option password ''
    option ifname 'eth0'
    option domain ''

Refs