From 392d770fd5202526fd2153921602ed36fac41b9a Mon Sep 17 00:00:00 2001
From: Sergei A Mamonov <mrqwer88@gmail.com>
Date: Sat, 14 May 2016 01:09:38 +0300
Subject: [PATCH 1/2] add netfilter to vzlist output

---
 include/vzlist.h |  1 +
 src/vzlist.c     | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/vzlist.h b/include/vzlist.h
index c1b7f98..21e6063 100644
--- a/include/vzlist.h
+++ b/include/vzlist.h
@@ -117,6 +117,7 @@ struct Cveinfo {
 	unsigned long long features_mask;
 	unsigned long long features_known;
 	float vm_overcommit;
+	unsigned long nf_mask; /* netfilter */
 };
 
 #define RES_NONE	0
diff --git a/src/vzlist.c b/src/vzlist.c
index 695a1b4..3b28479 100644
--- a/src/vzlist.c
+++ b/src/vzlist.c
@@ -47,6 +47,7 @@
 #include "image.h"
 #include "vzfeatures.h"
 #include "io.h"
+#include "iptables.h"
 
 static struct Cveinfo *veinfo = NULL;
 static int n_veinfo = 0;
@@ -398,6 +399,17 @@ static void print_layout(struct Cveinfo *p, int index)
 				"%-6s",	layout2str(p->layout));
 }
 
+
+
+static void print_netfilter(struct Cveinfo *p, int index)
+{
+	if (fmt_json)
+		print_json_str(netfilter_mask2str(p->nf_mask));
+	else
+		p_buf += snprintf(p_buf, e_buf - p_buf,
+				"%-6s",	netfilter_mask2str(p->nf_mask));
+}
+
 static void print_features(struct Cveinfo *p, int index)
 {
 	int r;
@@ -767,6 +779,7 @@ UBC_FIELD(swappages, SWAPP),
 {"disabled", "DISABL", "%6s", 0, RES_NONE, print_disabled, none_sort_fn},
 {"vm_overcommit", "VM_OVC", "%6s", 0, RES_NONE,
 	print_vm_overcommit, none_sort_fn},
+{"netfilter", "NETFILTER", "%-15s", 0, RES_NONE, print_netfilter, none_sort_fn},
 };
 
 static void *x_malloc(int size)
@@ -1151,6 +1164,7 @@ FOR_ALL_UBC(MERGE_UBC)
 	if (opt->origin_sample != NULL)
 		ve->origin_sample = strdup(opt->origin_sample);
 	ve->layout = res->fs.layout;
+	ve->nf_mask = res->env.nf_mask;
 }
 
 static int read_ves_param()

From bc860b83f72d221f37b4c563c8b7a6e5a33a9902 Mon Sep 17 00:00:00 2001
From: Sergei A Mamonov <mrqwer88@gmail.com>
Date: Sat, 14 May 2016 03:23:09 +0300
Subject: [PATCH 2/2] Add capability to vzlist output Fix first delimiter skip
 in build_cap_str

---
 include/cap.h    | 11 ++++++++
 include/vzlist.h |  5 +++-
 src/lib/cap.c    | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/vzlist.c     | 16 +++++++++++-
 4 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/include/cap.h b/include/cap.h
index ecbdb1d..916ee6d 100644
--- a/include/cap.h
+++ b/include/cap.h
@@ -65,4 +65,15 @@ int vps_set_cap(envid_t veid, struct env_param *env, cap_param *cap,
 void build_cap_str(cap_param *new, cap_param *old, const char *delim,
 		char *buf, int len);
 
+/** only retrun in string format for output.
+ *
+ * @param cap		capability mask.
+ * @param buf		merged capabilities in string format.
+ * @param len		max size of buf string.
+ */
+void cap_param2str(cap_param *cap, const char *delim,
+		char *buf, int len);
+
+void print_json_cap(cap_param *cap);
+
 #endif
diff --git a/include/vzlist.h b/include/vzlist.h
index 21e6063..ede5f6f 100644
--- a/include/vzlist.h
+++ b/include/vzlist.h
@@ -30,6 +30,8 @@
 
 #define MAXCPUUNITS	500000
 
+#include "cap.h"
+
 enum {
 	VE_RUNNING,
 	VE_STOPPED,
@@ -117,7 +119,8 @@ struct Cveinfo {
 	unsigned long long features_mask;
 	unsigned long long features_known;
 	float vm_overcommit;
-	unsigned long nf_mask; /* netfilter */
+	unsigned long nf_mask; // netfilter
+	cap_param cap; // capability
 };
 
 #define RES_NONE	0
diff --git a/src/lib/cap.c b/src/lib/cap.c
index 4937e49..31a5e04 100644
--- a/src/lib/cap.c
+++ b/src/lib/cap.c
@@ -19,6 +19,7 @@
 #include <linux/unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <ctype.h>
 #include <errno.h>
 #include <sys/syscall.h>
 #include <unistd.h>
@@ -170,6 +171,7 @@ void build_cap_str(cap_param *new, cap_param *old, const char *delim,
 		char *buf, int len)
 {
 	unsigned int i;
+	unsigned int j = 0;
 	int r;
 	char *sp, *ep;
 
@@ -191,7 +193,7 @@ void build_cap_str(cap_param *new, cap_param *old, const char *delim,
 		else
 			continue;
 		r = snprintf(sp, ep - sp, "%s%s:%s",
-				i == 0 ? "" : delim,
+				j++ == 0 ? "" : delim,
 				cap_names[i],
 				op == 1 ? "on" : "off");
 		if (r < 0 || sp + r >= ep)
@@ -200,6 +202,78 @@ void build_cap_str(cap_param *new, cap_param *old, const char *delim,
 	}
 }
 
+/** only retrun in string format for output.
+ *
+ * @param cap		capability mask.
+ * @param buf		merged capabilities in string format.
+ * @param len		max size of buf string.
+ */
+void cap_param2str(cap_param *cap, const char *delim,
+		char *buf, int len)
+{
+	unsigned int i;
+	unsigned int j = 0;
+	int r;
+	char *sp, *ep;
+	
+	unsigned int l = 0;
+	char lc[64] = "\0";
+
+	sp = buf;
+	ep = buf + len;
+	for (i = 0; i < ARRAY_SIZE(cap_names); i++) {
+		int op = 0;
+
+		if (CAP_TO_MASK(i) & cap->on)
+			op = 1;
+		else if (CAP_TO_MASK(i) & cap->off)
+			op = 2;
+		else
+			continue;
+		for (l=0; cap_names[i][l]; l++)
+			lc[l] = tolower(cap_names[i][l]);
+
+		r = snprintf(sp, ep - sp, "%s%s:%s",
+				j++ == 0 ? "" : delim,
+				lc,
+				op == 1 ? "on" : "off");
+		if (r < 0 || sp + r >= ep)
+			break;
+		sp += r;
+	}
+}
+
+void print_json_cap(cap_param *cap)
+{
+	unsigned int i, j = 0;
+	unsigned int l = 0;
+	char lc[64] = "\0";
+
+	for (i = 0; i < ARRAY_SIZE(cap_names); i++) {
+		int op = 0;
+
+		if (CAP_TO_MASK(i) & cap->on)
+			op = 1;
+		else if (CAP_TO_MASK(i) & cap->off)
+			op = 2;
+		else
+			continue;
+
+		for (l=0; cap_names[i][l]; l++)
+			lc[l] = tolower(cap_names[i][l]);
+
+		printf("%s      \"%s\": %s",
+				j++ == 0 ? "{\n" : ",\n",
+				lc,
+				op ? "true" : "false");
+	}
+
+	if (j)
+		printf("\n    }");
+	else
+		printf("null");
+}
+
 static int set_cap_bound(cap_t mask)
 {
 	int i;
diff --git a/src/vzlist.c b/src/vzlist.c
index 3b28479..a9c262e 100644
--- a/src/vzlist.c
+++ b/src/vzlist.c
@@ -407,7 +407,19 @@ static void print_netfilter(struct Cveinfo *p, int index)
 		print_json_str(netfilter_mask2str(p->nf_mask));
 	else
 		p_buf += snprintf(p_buf, e_buf - p_buf,
-				"%-6s",	netfilter_mask2str(p->nf_mask));
+				"%-15s",	netfilter_mask2str(p->nf_mask));
+}
+
+static void print_capability(struct Cveinfo *p, int index)
+{
+	if (fmt_json)
+		return print_json_cap(&p->cap);
+
+	char buf[STR_SIZE] = "-";
+	//build_cap_str(&p->cap, &p->cap, ",", buf, sizeof(buf));
+	cap_param2str(&p->cap, ",", buf, sizeof(buf));
+		p_buf += snprintf(p_buf, e_buf - p_buf,
+				"%-15s", buf);
 }
 
 static void print_features(struct Cveinfo *p, int index)
@@ -780,6 +792,7 @@ UBC_FIELD(swappages, SWAPP),
 {"vm_overcommit", "VM_OVC", "%6s", 0, RES_NONE,
 	print_vm_overcommit, none_sort_fn},
 {"netfilter", "NETFILTER", "%-15s", 0, RES_NONE, print_netfilter, none_sort_fn},
+{"capability", "CAPABILITY", "%-15s", 0, RES_NONE, print_capability, none_sort_fn},
 };
 
 static void *x_malloc(int size)
@@ -1165,6 +1178,7 @@ FOR_ALL_UBC(MERGE_UBC)
 		ve->origin_sample = strdup(opt->origin_sample);
 	ve->layout = res->fs.layout;
 	ve->nf_mask = res->env.nf_mask;
+	ve->cap = res->cap;
 }
 
 static int read_ves_param()
