From: Felix Fietkau Date: Sat, 10 Sep 2011 16:34:43 +0000 (+0200) Subject: fix invoking shell protocol handler scripts X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=commitdiff_plain;h=c601d036d6e9efce0c31eecd0fc66a716f41f2a3 fix invoking shell protocol handler scripts --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 43ced00..b264b1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,4 +21,4 @@ ADD_EXECUTABLE(netifd config.c device.c bridge.c vlan.c ubus.c system-dummy.c) -TARGET_LINK_LIBRARIES(netifd ubox ubus uci json) +TARGET_LINK_LIBRARIES(netifd ubox ubus uci json blobmsg_json) diff --git a/config/network b/config/network index 2b4549d..6e9d7a6 100644 --- a/config/network +++ b/config/network @@ -34,3 +34,8 @@ config interface lan2 option netmask 255.255.255.0 option gateway 192.168.1.2 +config interface wan + option proto pppoe + option ifname br-lan2 + option username foo + option password bar diff --git a/proto-shell.c b/proto-shell.c index 351e0bf..84d1c9c 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -13,7 +13,7 @@ #include "proto.h" static LIST_HEAD(handlers); -static int proto_fd, main_fd; +static int proto_fd; struct proto_shell_handler { struct list_head list; @@ -25,21 +25,69 @@ struct proto_shell_handler { struct proto_shell_state { struct interface_proto_state proto; + struct proto_shell_handler *handler; struct blob_attr *config; }; -#define DUMP_SUFFIX " dump" +#define DUMP_SUFFIX " '' dump" + +static int run_script(const char **argv) +{ + int pid, ret; + + if ((pid = fork()) < 0) + return -1; + + if (!pid) { + fchdir(proto_fd); + execvp(argv[0], (char **) argv); + exit(127); + } + + if (waitpid(pid, &ret, 0) == -1) + ret = -1; + + if (ret > 0) + return -ret; + + return 0; +} static int proto_shell_handler(struct interface_proto_state *proto, enum interface_proto_cmd cmd, bool force) { + struct proto_shell_state *state; + struct proto_shell_handler *handler; + const char *argv[5]; + char *config; + int ret; + + state = container_of(proto, struct proto_shell_state, proto); + handler = state->handler; + + config = blobmsg_format_json(state->config, true); + if (!config) + return -1; + + argv[0] = handler->script_name; + argv[1] = handler->proto.name; + argv[2] = "teardown"; + argv[3] = config; + argv[4] = NULL; + switch(cmd) { case PROTO_CMD_SETUP: + argv[2] = "setup"; + /* fall through */ case PROTO_CMD_TEARDOWN: + ret = run_script(argv); break; } - return 0; + + free(config); + + return ret; } static void @@ -66,6 +114,7 @@ proto_shell_attach(const struct proto_handler *h, struct interface *iface, memcpy(state->config, attr, blob_pad_len(attr)); state->proto.free = proto_shell_free; state->proto.handler = proto_shell_handler; + state->handler = container_of(h, struct proto_shell_handler, proto); return &state->proto; @@ -228,6 +277,7 @@ static void proto_shell_add_script(const char *name) void __init proto_shell_init(void) { glob_t g; + int main_fd; int i; main_fd = open(".", O_RDONLY | O_DIRECTORY); @@ -250,11 +300,7 @@ void __init proto_shell_init(void) for (i = 0; i < g.gl_pathc; i++) proto_shell_add_script(g.gl_pathv[i]); - if (list_empty(&handlers)) - close(proto_fd); - close_cur: fchdir(main_fd); - if (list_empty(&handlers)) - close(main_fd); + close(main_fd); } diff --git a/proto/netifd-proto.sh b/proto/netifd-proto.sh index 3764281..b91863f 100755 --- a/proto/netifd-proto.sh +++ b/proto/netifd-proto.sh @@ -26,7 +26,11 @@ add_default_handler() { esac } -case "$1" in +proto="$1" +cmd="$2" +data="$3" + +case "$cmd" in dump) add_protocol() { immediate=0 @@ -45,7 +49,13 @@ case "$1" in ;; *) add_protocol() { - return; + [[ "$proto" == "$1" ]] || return 0 + + case "$cmd" in + setup) eval "$1_setup \"\$data\"" ;; + teardown) eval "$1_teardown \"\$data\"" ;; + *) return 1 ;; + esac } ;; esac diff --git a/proto/ppp.sh b/proto/ppp.sh index 8dd97c0..9a5816b 100755 --- a/proto/ppp.sh +++ b/proto/ppp.sh @@ -9,7 +9,7 @@ ppp_init_config() { } ppp_setup() { - return + echo "ppp_setup: $1" } ppp_teardown() { @@ -30,4 +30,12 @@ pppoe_init() { return } +pppoe_setup() { + echo "pppoe_setup: $1" +} + +pppoe_teardown() { + return +} + add_protocol pppoe