fix invoking shell protocol handler scripts
authorFelix Fietkau <nbd@openwrt.org>
Sat, 10 Sep 2011 16:34:43 +0000 (18:34 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 10 Sep 2011 16:34:43 +0000 (18:34 +0200)
CMakeLists.txt
config/network
proto-shell.c
proto/netifd-proto.sh
proto/ppp.sh

index 43ced00..b264b1e 100644 (file)
@@ -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)
index 2b4549d..6e9d7a6 100644 (file)
@@ -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
index 351e0bf..84d1c9c 100644 (file)
@@ -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);
 }
index 3764281..b91863f 100755 (executable)
@@ -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
index 8dd97c0..9a5816b 100755 (executable)
@@ -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