ambrop7 14 лет назад
Родитель
Сommit
c40919afa3

+ 1 - 0
blog_channels.txt

@@ -28,6 +28,7 @@ ncd_alias 4
 ncd_process_manager 4
 ncd_process_manager 4
 ncd_ondemand 4
 ncd_ondemand 4
 ncd_foreach 4
 ncd_foreach 4
+ncd_choose 4
 ncd_net_backend_waitdevice 4
 ncd_net_backend_waitdevice 4
 ncd_net_backend_waitlink 4
 ncd_net_backend_waitlink 4
 ncd_net_backend_badvpn 4
 ncd_net_backend_badvpn 4

+ 4 - 0
generated/blog_channel_ncd_choose.h

@@ -0,0 +1,4 @@
+#ifdef BLOG_CURRENT_CHANNEL
+#undef BLOG_CURRENT_CHANNEL
+#endif
+#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_choose

+ 66 - 65
generated/blog_channels_defines.h

@@ -28,68 +28,69 @@
 #define BLOG_CHANNEL_ncd_process_manager 27
 #define BLOG_CHANNEL_ncd_process_manager 27
 #define BLOG_CHANNEL_ncd_ondemand 28
 #define BLOG_CHANNEL_ncd_ondemand 28
 #define BLOG_CHANNEL_ncd_foreach 29
 #define BLOG_CHANNEL_ncd_foreach 29
-#define BLOG_CHANNEL_ncd_net_backend_waitdevice 30
-#define BLOG_CHANNEL_ncd_net_backend_waitlink 31
-#define BLOG_CHANNEL_ncd_net_backend_badvpn 32
-#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 33
-#define BLOG_CHANNEL_ncd_net_backend_rfkill 34
-#define BLOG_CHANNEL_ncd_net_up 35
-#define BLOG_CHANNEL_ncd_net_dns 36
-#define BLOG_CHANNEL_ncd_net_iptables 37
-#define BLOG_CHANNEL_ncd_net_ipv4_addr 38
-#define BLOG_CHANNEL_ncd_net_ipv4_route 39
-#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 40
-#define BLOG_CHANNEL_ncd_net_ipv4_arp_probe 41
-#define BLOG_CHANNEL_ncd_net_watch_interfaces 42
-#define BLOG_CHANNEL_ncd_sys_watch_input 43
-#define BLOG_CHANNEL_ncd_sys_evdev 44
-#define BLOG_CHANNEL_ncd_sys_watch_directory 45
-#define BLOG_CHANNEL_StreamPeerIO 46
-#define BLOG_CHANNEL_DatagramPeerIO 47
-#define BLOG_CHANNEL_BReactor 48
-#define BLOG_CHANNEL_BSignal 49
-#define BLOG_CHANNEL_FragmentProtoAssembler 50
-#define BLOG_CHANNEL_BPredicate 51
-#define BLOG_CHANNEL_ServerConnection 52
-#define BLOG_CHANNEL_Listener 53
-#define BLOG_CHANNEL_DataProto 54
-#define BLOG_CHANNEL_FrameDecider 55
-#define BLOG_CHANNEL_BSocksClient 56
-#define BLOG_CHANNEL_BDHCPClientCore 57
-#define BLOG_CHANNEL_BDHCPClient 58
-#define BLOG_CHANNEL_NCDIfConfig 59
-#define BLOG_CHANNEL_BUnixSignal 60
-#define BLOG_CHANNEL_BProcess 61
-#define BLOG_CHANNEL_PRStreamSink 62
-#define BLOG_CHANNEL_PRStreamSource 63
-#define BLOG_CHANNEL_PacketProtoDecoder 64
-#define BLOG_CHANNEL_DPRelay 65
-#define BLOG_CHANNEL_BThreadWork 66
-#define BLOG_CHANNEL_DPReceive 67
-#define BLOG_CHANNEL_BInputProcess 68
-#define BLOG_CHANNEL_NCDUdevMonitorParser 69
-#define BLOG_CHANNEL_NCDUdevMonitor 70
-#define BLOG_CHANNEL_NCDUdevCache 71
-#define BLOG_CHANNEL_NCDUdevManager 72
-#define BLOG_CHANNEL_BTime 73
-#define BLOG_CHANNEL_BEncryption 74
-#define BLOG_CHANNEL_SPProtoDecoder 75
-#define BLOG_CHANNEL_LineBuffer 76
-#define BLOG_CHANNEL_BTap 77
-#define BLOG_CHANNEL_lwip 78
-#define BLOG_CHANNEL_NCDConfigParser 79
-#define BLOG_CHANNEL_nsskey 80
-#define BLOG_CHANNEL_addr 81
-#define BLOG_CHANNEL_PasswordListener 82
-#define BLOG_CHANNEL_NCDInterfaceMonitor 83
-#define BLOG_CHANNEL_NCDRfkillMonitor 84
-#define BLOG_CHANNEL_udpgw 85
-#define BLOG_CHANNEL_UdpGwClient 86
-#define BLOG_CHANNEL_SocksUdpGwClient 87
-#define BLOG_CHANNEL_BNetwork 88
-#define BLOG_CHANNEL_BConnection 89
-#define BLOG_CHANNEL_BSSLConnection 90
-#define BLOG_CHANNEL_BDatagram 91
-#define BLOG_CHANNEL_PeerChat 92
-#define BLOG_CHANNEL_BArpProbe 93
-#define BLOG_NUM_CHANNELS 94
+#define BLOG_CHANNEL_ncd_choose 30
+#define BLOG_CHANNEL_ncd_net_backend_waitdevice 31
+#define BLOG_CHANNEL_ncd_net_backend_waitlink 32
+#define BLOG_CHANNEL_ncd_net_backend_badvpn 33
+#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 34
+#define BLOG_CHANNEL_ncd_net_backend_rfkill 35
+#define BLOG_CHANNEL_ncd_net_up 36
+#define BLOG_CHANNEL_ncd_net_dns 37
+#define BLOG_CHANNEL_ncd_net_iptables 38
+#define BLOG_CHANNEL_ncd_net_ipv4_addr 39
+#define BLOG_CHANNEL_ncd_net_ipv4_route 40
+#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 41
+#define BLOG_CHANNEL_ncd_net_ipv4_arp_probe 42
+#define BLOG_CHANNEL_ncd_net_watch_interfaces 43
+#define BLOG_CHANNEL_ncd_sys_watch_input 44
+#define BLOG_CHANNEL_ncd_sys_evdev 45
+#define BLOG_CHANNEL_ncd_sys_watch_directory 46
+#define BLOG_CHANNEL_StreamPeerIO 47
+#define BLOG_CHANNEL_DatagramPeerIO 48
+#define BLOG_CHANNEL_BReactor 49
+#define BLOG_CHANNEL_BSignal 50
+#define BLOG_CHANNEL_FragmentProtoAssembler 51
+#define BLOG_CHANNEL_BPredicate 52
+#define BLOG_CHANNEL_ServerConnection 53
+#define BLOG_CHANNEL_Listener 54
+#define BLOG_CHANNEL_DataProto 55
+#define BLOG_CHANNEL_FrameDecider 56
+#define BLOG_CHANNEL_BSocksClient 57
+#define BLOG_CHANNEL_BDHCPClientCore 58
+#define BLOG_CHANNEL_BDHCPClient 59
+#define BLOG_CHANNEL_NCDIfConfig 60
+#define BLOG_CHANNEL_BUnixSignal 61
+#define BLOG_CHANNEL_BProcess 62
+#define BLOG_CHANNEL_PRStreamSink 63
+#define BLOG_CHANNEL_PRStreamSource 64
+#define BLOG_CHANNEL_PacketProtoDecoder 65
+#define BLOG_CHANNEL_DPRelay 66
+#define BLOG_CHANNEL_BThreadWork 67
+#define BLOG_CHANNEL_DPReceive 68
+#define BLOG_CHANNEL_BInputProcess 69
+#define BLOG_CHANNEL_NCDUdevMonitorParser 70
+#define BLOG_CHANNEL_NCDUdevMonitor 71
+#define BLOG_CHANNEL_NCDUdevCache 72
+#define BLOG_CHANNEL_NCDUdevManager 73
+#define BLOG_CHANNEL_BTime 74
+#define BLOG_CHANNEL_BEncryption 75
+#define BLOG_CHANNEL_SPProtoDecoder 76
+#define BLOG_CHANNEL_LineBuffer 77
+#define BLOG_CHANNEL_BTap 78
+#define BLOG_CHANNEL_lwip 79
+#define BLOG_CHANNEL_NCDConfigParser 80
+#define BLOG_CHANNEL_nsskey 81
+#define BLOG_CHANNEL_addr 82
+#define BLOG_CHANNEL_PasswordListener 83
+#define BLOG_CHANNEL_NCDInterfaceMonitor 84
+#define BLOG_CHANNEL_NCDRfkillMonitor 85
+#define BLOG_CHANNEL_udpgw 86
+#define BLOG_CHANNEL_UdpGwClient 87
+#define BLOG_CHANNEL_SocksUdpGwClient 88
+#define BLOG_CHANNEL_BNetwork 89
+#define BLOG_CHANNEL_BConnection 90
+#define BLOG_CHANNEL_BSSLConnection 91
+#define BLOG_CHANNEL_BDatagram 92
+#define BLOG_CHANNEL_PeerChat 93
+#define BLOG_CHANNEL_BArpProbe 94
+#define BLOG_NUM_CHANNELS 95

+ 1 - 0
generated/blog_channels_list.h

@@ -28,6 +28,7 @@
 {.name = "ncd_process_manager", .loglevel = 4},
 {.name = "ncd_process_manager", .loglevel = 4},
 {.name = "ncd_ondemand", .loglevel = 4},
 {.name = "ncd_ondemand", .loglevel = 4},
 {.name = "ncd_foreach", .loglevel = 4},
 {.name = "ncd_foreach", .loglevel = 4},
+{.name = "ncd_choose", .loglevel = 4},
 {.name = "ncd_net_backend_waitdevice", .loglevel = 4},
 {.name = "ncd_net_backend_waitdevice", .loglevel = 4},
 {.name = "ncd_net_backend_waitlink", .loglevel = 4},
 {.name = "ncd_net_backend_waitlink", .loglevel = 4},
 {.name = "ncd_net_backend_badvpn", .loglevel = 4},
 {.name = "ncd_net_backend_badvpn", .loglevel = 4},

+ 1 - 0
ncd/CMakeLists.txt

@@ -62,6 +62,7 @@ add_executable(badvpn-ncd
     modules/process_manager.c
     modules/process_manager.c
     modules/ondemand.c
     modules/ondemand.c
     modules/foreach.c
     modules/foreach.c
+    modules/choose.c
     modules/net_backend_waitdevice.c
     modules/net_backend_waitdevice.c
     modules/net_backend_waitlink.c
     modules/net_backend_waitlink.c
     modules/net_backend_badvpn.c
     modules/net_backend_badvpn.c

+ 160 - 0
ncd/modules/choose.c

@@ -0,0 +1,160 @@
+/**
+ * @file choose.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * @section DESCRIPTION
+ * 
+ * Multiple value selection based on boolean conditions.
+ * 
+ * Synopsis:
+ *   choose({{string cond1, result1}, ..., {string condN, resultN}}, default_result)
+ * 
+ * Variables:
+ *   (empty) - If cond1="true" then result1,
+ *             else if cond2="true" then result2,
+ *             ...,
+ *             else default_result.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <ncd/NCDModule.h>
+
+#include <generated/blog_channel_ncd_choose.h>
+
+#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+
+struct instance {
+    NCDModuleInst *i;
+    NCDValue *result;
+};
+
+static void func_new (NCDModuleInst *i)
+{
+    // allocate instance
+    struct instance *o = malloc(sizeof(*o));
+    if (!o) {
+        ModuleLog(i, BLOG_ERROR, "failed to allocate instance");
+        goto fail0;
+    }
+    NCDModuleInst_Backend_SetUser(i, o);
+    
+    // init arguments
+    o->i = i;
+    
+    // read arguments
+    NCDValue *arg_choices;
+    NCDValue *arg_default_result;
+    if (!NCDValue_ListRead(i->args, 2, &arg_choices, &arg_default_result)) {
+        ModuleLog(i, BLOG_ERROR, "wrong arity");
+        goto fail1;
+    }
+    if (NCDValue_Type(arg_choices) != NCDVALUE_LIST) {
+        ModuleLog(i, BLOG_ERROR, "wrong type");
+        goto fail1;
+    }
+    
+    // set no result
+    o->result = NULL;
+    
+    // iterate choices
+    for (NCDValue *c = NCDValue_ListFirst(arg_choices); c; c = NCDValue_ListNext(arg_choices, c)) {
+        // check choice type
+        if (NCDValue_Type(c) != NCDVALUE_LIST) {
+            ModuleLog(i, BLOG_ERROR, "wrong choice type");
+            goto fail1;
+        }
+        
+        // read choice
+        NCDValue *c_cond;
+        NCDValue *c_result;
+        if (!NCDValue_ListRead(c, 2, &c_cond, &c_result)) {
+            ModuleLog(i, BLOG_ERROR, "wrong choice contents arity");
+            goto fail1;
+        }
+        if (NCDValue_Type(c_cond) != NCDVALUE_STRING) {
+            ModuleLog(i, BLOG_ERROR, "wrong choice condition type");
+            goto fail1;
+        }
+        
+        // update result
+        if (!o->result && !strcmp(NCDValue_StringValue(c_cond), "true")) {
+            o->result = c_result;
+        }
+    }
+    
+    // default?
+    if (!o->result) {
+        o->result = arg_default_result;
+    }
+    
+    // signal up
+    NCDModuleInst_Backend_Up(o->i);
+    return;
+    
+fail1:
+    free(o);
+fail0:
+    NCDModuleInst_Backend_SetError(i);
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static void func_die (void *vo)
+{
+    struct instance *o = vo;
+    NCDModuleInst *i = o->i;
+    
+    // free instance
+    free(o);
+    
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static int func_getvar (void *vo, const char *name, NCDValue *out)
+{
+    struct instance *o = vo;
+    
+    if (!strcmp(name, "")) {
+        if (!NCDValue_InitCopy(out, o->result)) {
+            ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitCopy failed");
+            return 0;
+        }
+        
+        return 1;
+    }
+    
+    return 0;
+}
+
+static const struct NCDModule modules[] = {
+    {
+        .type = "choose",
+        .func_new = func_new,
+        .func_die = func_die,
+        .func_getvar = func_getvar
+    }, {
+        .type = NULL
+    }
+};
+
+const struct NCDModuleGroup ncdmodule_choose = {
+    .modules = modules
+};

+ 2 - 0
ncd/modules/modules.h

@@ -52,6 +52,7 @@ extern const struct NCDModuleGroup ncdmodule_alias;
 extern const struct NCDModuleGroup ncdmodule_process_manager;
 extern const struct NCDModuleGroup ncdmodule_process_manager;
 extern const struct NCDModuleGroup ncdmodule_ondemand;
 extern const struct NCDModuleGroup ncdmodule_ondemand;
 extern const struct NCDModuleGroup ncdmodule_foreach;
 extern const struct NCDModuleGroup ncdmodule_foreach;
+extern const struct NCDModuleGroup ncdmodule_choose;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitdevice;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitdevice;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitlink;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitlink;
 extern const struct NCDModuleGroup ncdmodule_net_backend_badvpn;
 extern const struct NCDModuleGroup ncdmodule_net_backend_badvpn;
@@ -101,6 +102,7 @@ static const struct NCDModuleGroup *ncd_modules[] = {
     &ncdmodule_process_manager,
     &ncdmodule_process_manager,
     &ncdmodule_ondemand,
     &ncdmodule_ondemand,
     &ncdmodule_foreach,
     &ncdmodule_foreach,
+    &ncdmodule_choose,
     &ncdmodule_net_backend_waitdevice,
     &ncdmodule_net_backend_waitdevice,
     &ncdmodule_net_backend_waitlink,
     &ncdmodule_net_backend_waitlink,
     &ncdmodule_net_backend_badvpn,
     &ncdmodule_net_backend_badvpn,