From 7b0af307cd0f723bc341e8eec6b932a79d82a445 Mon Sep 17 00:00:00 2001
From: Patrick Martin <patrick.martin.r@gmail.com>
Date: Mon, 23 Jan 2017 15:58:21 -0800
Subject: [PATCH] fixed a few more things

---
 Makefile                  |  5 +++++
 include/iwinfo.h          |  4 ++++
 iwinfo_external_wrapper.c |  7 +++++--
 iwinfo_lib.c              | 33 +++++++++++++++++++++++++++++----
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 4a62205..2a39ec6 100644
--- a/Makefile
+++ b/Makefile
@@ -32,6 +32,11 @@ ifneq ($(filter nl80211,$(IWINFO_BACKENDS)),)
 	IWINFO_LIB_OBJ     += iwinfo_nl80211.o
 endif
 
+ifneq ($(filter external,$(IWINFO_BACKENDS)),)
+	IWINFO_CFLAGS  += -DUSE_EXTERNAL_BACKENDS
+	IWINFO_LIB_OBJ += iwinfo_external.o
+endif
+
 
 %.o: %.c
 	$(CC) $(IWINFO_CFLAGS) $(FPIC) -c -o $@ $<
diff --git a/include/iwinfo.h b/include/iwinfo.h
index bb2b20a..da1c27a 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -224,6 +224,10 @@ extern const struct iwinfo_ops wext_ops;
 extern const struct iwinfo_ops madwifi_ops;
 extern const struct iwinfo_ops nl80211_ops;
 extern const struct iwinfo_ops wl_ops;
+#ifdef USE_EXTERNAL_BACKENDS
+extern const struct iwinfo_ops external_ops;
+extern const struct iwinfo_ops external_placeholder_ops;
+#endif
 
 #include "iwinfo/utils.h"
 
diff --git a/iwinfo_external_wrapper.c b/iwinfo_external_wrapper.c
index a257de1..b0166fd 100644
--- a/iwinfo_external_wrapper.c
+++ b/iwinfo_external_wrapper.c
@@ -48,6 +48,7 @@ typedef struct {
 
 extern static struct iwinfo_ops ** backends;
 extern static struct iwinfo_ops * backends_template[];
+extern static size_t backends_count;
 
 iwinfo_ops * default_ops_list = NULL;
 iwinfo_ops * default_ops_list_without_external = NULL;
@@ -182,14 +183,15 @@ static int external_module_search(const char * ifname){
 			}
 			static iwinfo_ops ** old_backends = NULL;
 			if(old_backends != NULL) free(old_backends);
-			new_backends = malloc(sizeof(backends_template)+((custom_backend_max_index+1)*sizeof(iwinfo_ops*)));
-			memcpy(new_backends+1,backends,sizeof(backends_template)+(custom_backend_max_index*sizeof(iwinfo_ops*)));
+			new_backends = malloc((backends_count+1)*sizeof(iwinfo_ops*));
+			memcpy(new_backends+1,backends,backends_count*sizeof(iwinfo_ops*));
 			backends[1] = custom_ops;
 			old_backends = backends;
 			new_backends[0] = external_ops;
 			new_backends[1] = external_placeholder_ops;
 			new_backends[2] = custom_ops;
 			backends = new_backends;
+			backends_count++;
 		}
 	}
 	
@@ -218,6 +220,7 @@ static int external_getemptylist(const char * ifname,char * buf, int* len){
 
 static void external_close(void){
 	backends = default_ops_list;
+	backends_count = ARRAY_SIZE(backends_template);
 	for(unsigned int i=0; i<=custom_backend_max_index;i++){
 		custom_backend_list[i].backend->close();
 		if(!(custom_backend_list[i].flags & BFLAG_OPS_PROVIDED_BY_MODULE))free(custom_backend_list[i].backend);
diff --git a/iwinfo_lib.c b/iwinfo_lib.c
index fa9bb9f..2a5db76 100644
--- a/iwinfo_lib.c
+++ b/iwinfo_lib.c
@@ -323,7 +323,14 @@ const struct iwinfo_iso3166_label IWINFO_ISO3166_NAMES[] = {
 	{ 0,               "" }
 };
 
-static const struct iwinfo_ops *backends[] = {
+#ifdef USE_EXTERNAL_BACKENDS
+static struct iwinfo_ops **backends = NULL;
+static struct iwinfo_ops *backends_template[] = {
+	&external_ops, //This must always be the first entry because of the way the code adds backends.
+	&external_placeholder_ops, //placeholder for imported backend
+#elseif
+static struct iwinfo_ops *backends[] = {
+#endif
 #ifdef USE_NL80211
 	&nl80211_ops,
 #endif
@@ -336,6 +343,24 @@ static const struct iwinfo_ops *backends[] = {
 	&wext_ops,
 };
 
+#ifdef USE_EXTERNAL_BACKENDS
+static size_t backends_count = ARRAY_SIZE(backends_template);
+inline size_t _getbackendscount(){
+	static int backends_copyed = 0;
+	if(backends == NULL&&!first){
+		backends = (iwinfo_ops**)malloc(ARRAY_SIZE(backends_template)*sizeof(iwinfo_ops*));
+		for(size_t i = 0; i < ARRAY_SIZE(backends_template);i++){
+			backends[i] = backends_template[i];
+		}
+		backends_copyed = 1;
+	}
+	return backends_count;
+}
+#define BACKENDS_COUNT _getbackendscount()
+#elseif
+#define BACKENDS_COUNT ARRAY_SIZE(backends)
+#endif
+
 const char * iwinfo_type(const char *ifname)
 {
 	const struct iwinfo_ops *ops = iwinfo_backend(ifname);
@@ -349,7 +374,7 @@ const struct iwinfo_ops * iwinfo_backend(const char *ifname)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(backends); i++)
+	for (i = 0; i < BACKENDS_COUNT; i++)
 		if (backends[i]->probe(ifname))
 			return backends[i];
 
@@ -360,7 +385,7 @@ const struct iwinfo_ops * iwinfo_backend_by_name(const char *name)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(backends); i++)
+	for (i = 0; i < BACKENDS_COUNT; i++)
 		if (!strcmp(backends[i]->name, name))
 			return backends[i];
 
@@ -371,7 +396,7 @@ void iwinfo_finish(void)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(backends); i++)
+	for (i = 0; i < BACKENDS_COUNT; i++)
 		backends[i]->close();
 
 	iwinfo_close();
-- 
2.11.0.windows.3

