mirror of
https://github.com/openNDS/openNDS.git
synced 2026-05-04 03:01:32 -04:00
@@ -60,9 +60,9 @@ author = 'The openNDS Contributors'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '6.0.1beta'
|
||||
version = '7.0.0beta'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '6.0.1beta'
|
||||
release = '7.0.0beta'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -150,7 +150,7 @@ if (isset($_GET["status"])) {
|
||||
";
|
||||
|
||||
$hid=$redir="status";
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir $custom);
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir, $custom);
|
||||
footer($imagepath);
|
||||
exit(0);
|
||||
}
|
||||
@@ -192,7 +192,7 @@ if ($fullname == "" or $email == "") {
|
||||
<br>
|
||||
";
|
||||
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir $custom);
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir, $custom);
|
||||
}
|
||||
} else {
|
||||
# Output the "Thankyou page" with a continue button
|
||||
@@ -216,7 +216,7 @@ if ($fullname == "" or $email == "") {
|
||||
<input type=\"hidden\" name=\"redir\" value=\"".$redir."\"><br>
|
||||
<input type=\"submit\" value=\"Continue\" >
|
||||
</form><hr>\n";
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir $custom);
|
||||
read_terms($me, $clientip, $gatewayname, $gatewayaddress, $hid, $redir, $custom);
|
||||
|
||||
# In this example we have decided to log all clients who are granted access
|
||||
# Note: the web server daemon must have read and write permissions to the folder defined in $logpath
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#This software is released under the GNU GPL license.
|
||||
#
|
||||
# Warning - shebang sh is for compatibliity with busybox ash (eg on OpenWrt)
|
||||
# This is changed to bash automatically by Makefile for Debian
|
||||
# This is changed to bash automatically by Makefile for generic Linux
|
||||
#
|
||||
|
||||
|
||||
@@ -17,9 +17,11 @@ if [ -z $(command -v ip) ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $(command -v iw) ]; then
|
||||
if [ -z $(command -v iww) ]; then
|
||||
echo "iw utility not available" | logger -p "daemon.warn" -s -t "NDS-Library[$pid]"
|
||||
exit 1
|
||||
iwstatus=false
|
||||
else
|
||||
iwstatus=true
|
||||
fi
|
||||
|
||||
# mac address of client is passed as a command line argument
|
||||
@@ -57,28 +59,31 @@ if [ -z "$clientlocalif" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get list of wireless interfaces on this device
|
||||
# This list will contain all the wireless interfaces configured on the device
|
||||
# eg wlan0, wlan0-1, wlan1, wlan1-1 etc
|
||||
interface_list=$(iw dev | awk -F 'Interface ' 'NF>1{printf $2" "}')
|
||||
clientmeshif=""
|
||||
|
||||
# Scan the wireless interfaces on this device for the client mac
|
||||
for interface in $interface_list; do
|
||||
macscan=$(iw dev $interface station dump | awk -F " " 'match($s, "'"$mac"'")>0{printf $2}')
|
||||
if [ "$iwstatus" = true ]; then
|
||||
# Get list of wireless interfaces on this device
|
||||
# This list will contain all the wireless interfaces configured on the device
|
||||
# eg wlan0, wlan0-1, wlan1, wlan1-1 etc
|
||||
interface_list=$(iw dev | awk -F 'Interface ' 'NF>1{printf $2" "}')
|
||||
|
||||
if [ ! -z "$macscan" ]; then
|
||||
clientmeshif=""
|
||||
clientlocalif=$interface
|
||||
break
|
||||
else
|
||||
clientlocalip=$(ip -4 neigh | awk -F ' ' 'match($s,"'"$mac"' ")>0 {printf $1}')
|
||||
ping=$(ping -W 1 -c 1 $clientlocalip)
|
||||
meshmac=$(iw dev $interface mpp dump | awk -F "$mac " 'NF>1{printf $2}')
|
||||
if [ ! -z "$meshmac" ]; then
|
||||
clientmeshif=$meshmac
|
||||
# Scan the wireless interfaces on this device for the client mac
|
||||
for interface in $interface_list; do
|
||||
macscan=$(iw dev $interface station dump | awk -F " " 'match($s, "'"$mac"'")>0{printf $2}')
|
||||
|
||||
if [ ! -z "$macscan" ]; then
|
||||
clientlocalif=$interface
|
||||
break
|
||||
else
|
||||
clientlocalip=$(ip -4 neigh | awk -F ' ' 'match($s,"'"$mac"' ")>0 {printf $1}')
|
||||
ping=$(ping -W 1 -c 1 $clientlocalip)
|
||||
meshmac=$(iw dev $interface mpp dump | awk -F "$mac " 'NF>1{printf $2}')
|
||||
if [ ! -z "$meshmac" ]; then
|
||||
clientmeshif=$meshmac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Return the local interface the client is using, the mesh node mac address and the local mesh interface
|
||||
echo "$clientlocalif $clientmeshif"
|
||||
|
||||
@@ -28,6 +28,8 @@ function SendPostData($_p, $remote_url, $user_agent) {
|
||||
//open the stream and get the response
|
||||
$fp = @fopen($remote_url, 'r', false, $context);
|
||||
|
||||
$response = "";
|
||||
|
||||
if ($fp == TRUE) {
|
||||
$response = trim(stream_get_contents($fp));
|
||||
}
|
||||
|
||||
15
src/conf.h
15
src/conf.h
@@ -29,7 +29,7 @@
|
||||
#ifndef _CONF_H_
|
||||
#define _CONF_H_
|
||||
|
||||
#define VERSION "6.0.1beta"
|
||||
#define VERSION "7.0.0beta"
|
||||
|
||||
/*
|
||||
* Defines how many times should we try detecting the interface with the default route (in seconds).
|
||||
@@ -132,6 +132,17 @@ typedef struct _MAC_t {
|
||||
struct _MAC_t *next;
|
||||
} t_MAC;
|
||||
|
||||
// Walled Garden Ports
|
||||
typedef struct _WGP_t {
|
||||
unsigned int wgport;
|
||||
struct _WGP_t *next;
|
||||
} t_WGP;
|
||||
|
||||
// Walled Garden FQDNs
|
||||
typedef struct _WGFQDN_t {
|
||||
char *wgfqdn;
|
||||
struct _WGFQDN_t *next;
|
||||
} t_WGFQDN;
|
||||
|
||||
// Configuration structure
|
||||
typedef struct {
|
||||
@@ -195,6 +206,8 @@ typedef struct {
|
||||
int ip6; //@brief enable IPv6
|
||||
char *binauth; //@brief external authentication program
|
||||
char *preauth; //@brief external preauthentication program
|
||||
t_WGP walledgardenportlist; //@brief list of Walled Garden Ports
|
||||
t_WGFQDN *walledgardenfqdnlist; //@brief list of Walled Garden FQDNs
|
||||
} s_config;
|
||||
|
||||
// @brief Get the current gateway configuration
|
||||
|
||||
@@ -83,7 +83,7 @@ usage(void)
|
||||
"\n"
|
||||
" customstring is a custom string that will be passed to BinAuth.\n"
|
||||
"\n"
|
||||
" Example: ndsctl auth 1400 300 1500 500000 1000000 \"This is a Custom String\"\n"
|
||||
" Example: ndsctl auth 10.13.1.138 1400 300 1500 500000 1000000 \"This is a Custom String\"\n"
|
||||
"\n"
|
||||
" deauth mac|ip|token\n"
|
||||
" Deauthenticate user with specified mac, ip or token\n\n"
|
||||
|
||||
192
src/util.c
192
src/util.c
@@ -227,9 +227,10 @@ get_iface_ip(const char ifname[], int ip6)
|
||||
snprintf(iptype, sizeof(iptype), "inet");
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "ip address | grep -A2 ': %s' | grep '%s ' | awk '{print $2}' | awk -F'/' 'NR==1 {printf $1}'",
|
||||
snprintf(cmd, sizeof(cmd), "ip address | grep -A2 ': %s' | grep '%s ' | awk '$NF == \"%s\" {print $2}' | awk -F'/' 'NR==1 {printf $1}'",
|
||||
ifname,
|
||||
iptype
|
||||
iptype,
|
||||
ifname
|
||||
);
|
||||
|
||||
debug(LOG_NOTICE, "Attempting to Bind to interface: %s", ifname);
|
||||
@@ -457,6 +458,7 @@ ndsctl_status(FILE *fp)
|
||||
}
|
||||
|
||||
fprintf(fp, "Client Check Interval: %ds\n", config->checkinterval);
|
||||
fprintf(fp, "Rate Check Window: %d check intervals (%ds)\n", config->rate_check_window, (config->rate_check_window * config->checkinterval));
|
||||
fprintf(fp, "Preauth Idle Timeout: %dm\n", config->preauth_idle_timeout);
|
||||
fprintf(fp, "Auth Idle Timeout: %dm\n", config->auth_idle_timeout);
|
||||
|
||||
@@ -464,20 +466,28 @@ ndsctl_status(FILE *fp)
|
||||
fprintf(fp, "Redirect URL: %s\n", config->redirectURL);
|
||||
}
|
||||
|
||||
fprintf(fp, "Traffic control: %s\n", config->traffic_control ? "yes" : "no");
|
||||
|
||||
if (config->traffic_control) {
|
||||
if (config->download_rate > 0) {
|
||||
fprintf(fp, "Download rate limit: %llu kbit/s\n", config->download_rate);
|
||||
} else {
|
||||
fprintf(fp, "Download rate limit: none\n");
|
||||
}
|
||||
if (config->upload_rate > 0) {
|
||||
fprintf(fp, "Upload rate limit: %llu kbit/s\n", config->upload_rate);
|
||||
} else {
|
||||
fprintf(fp, "Upload rate limit: none\n");
|
||||
}
|
||||
if (config->download_rate > 0) {
|
||||
fprintf(fp, "Download rate limit (default per client): %llu kbit/s\n", config->download_rate);
|
||||
} else {
|
||||
fprintf(fp, "Download rate limit (default per client): no limit\n");
|
||||
}
|
||||
if (config->upload_rate > 0) {
|
||||
fprintf(fp, "Upload rate limit (default per client): %llu kbit/s\n", config->upload_rate);
|
||||
} else {
|
||||
fprintf(fp, "Upload rate limit (default per client): no limit\n");
|
||||
}
|
||||
|
||||
if (config->download_quota > 0) {
|
||||
fprintf(fp, "Download quota (default per client): %llu kB\n", config->download_quota);
|
||||
} else {
|
||||
fprintf(fp, "Download quota (default per client): no limit\n");
|
||||
}
|
||||
if (config->upload_quota > 0) {
|
||||
fprintf(fp, "Upload quota (default per client): %llu kB\n", config->upload_quota);
|
||||
} else {
|
||||
fprintf(fp, "Upload quota (default per client): no limit\n");
|
||||
}
|
||||
|
||||
|
||||
download_bytes = iptables_fw_total_download();
|
||||
fprintf(fp, "Total download: %llu kByte", download_bytes / 1000);
|
||||
@@ -528,9 +538,32 @@ ndsctl_status(FILE *fp)
|
||||
}
|
||||
|
||||
fprintf(fp, " Token: %s\n", client->token ? client->token : "none");
|
||||
|
||||
fprintf(fp, " State: %s\n", fw_connection_state_as_string(client->fw_connection_state));
|
||||
|
||||
if (client->upload_rate == 0) {
|
||||
fprintf(fp, " Upload rate limit: not set\n");
|
||||
} else {
|
||||
fprintf(fp, " Upload rate limit: %llu kb/s\n", client->upload_rate);
|
||||
}
|
||||
|
||||
if (client->download_rate == 0) {
|
||||
fprintf(fp, " Download rate limit: not set\n");
|
||||
} else {
|
||||
fprintf(fp, " Download rate limit: %llu kb/s\n", client->download_rate);
|
||||
}
|
||||
|
||||
if (client->upload_quota == 0) {
|
||||
fprintf(fp, " Upload quota: not set\n");
|
||||
} else {
|
||||
fprintf(fp, " Upload quota: %llu kB\n", client->upload_quota);
|
||||
}
|
||||
|
||||
if (client->download_quota == 0) {
|
||||
fprintf(fp, " Download quota: not set\n");
|
||||
} else {
|
||||
fprintf(fp, " Download quota: %llu kB\n", client->download_quota);
|
||||
}
|
||||
|
||||
download_bytes = client->counters.incoming;
|
||||
upload_bytes = client->counters.outgoing;
|
||||
durationsecs = now - client->session_start;
|
||||
@@ -540,9 +573,15 @@ ndsctl_status(FILE *fp)
|
||||
durationsecs = 1;
|
||||
}
|
||||
|
||||
fprintf(fp, " Download: %llu kByte; avg: %.2f kbit/s\n Upload: %llu kByte; avg: %.2f kbit/s\n\n",
|
||||
download_bytes / 1000, ((double)download_bytes) / 125 / durationsecs,
|
||||
upload_bytes / 1000, ((double)upload_bytes) / 125 / durationsecs);
|
||||
fprintf(fp, " Upload this session: %llu kB; Session avg: %.2f kb/s\n",
|
||||
upload_bytes / 1000,
|
||||
((double)upload_bytes) / 125 / durationsecs)
|
||||
;
|
||||
|
||||
fprintf(fp, " Download this session: %llu kB; Session avg: %.2f kb/s\n\n",
|
||||
download_bytes / 1000,
|
||||
((double)download_bytes) / 125 / durationsecs)
|
||||
;
|
||||
|
||||
indx++;
|
||||
client = client->next;
|
||||
@@ -592,6 +631,7 @@ ndsctl_status(FILE *fp)
|
||||
fprintf(fp, "========\n");
|
||||
}
|
||||
|
||||
// TODO Deprecated ndsctl clients, remove at future date
|
||||
void
|
||||
ndsctl_clients(FILE *fp)
|
||||
{
|
||||
@@ -637,6 +677,9 @@ ndsctl_clients(FILE *fp)
|
||||
fprintf(fp, "uploaded=%llu\n", upload_bytes/1000);
|
||||
fprintf(fp, "avg_up_speed=%.2f\n\n", ((double)upload_bytes) / 125 / durationsecs);
|
||||
|
||||
fprintf(fp, "Warning - ndsctl clients is deprecated and will be removed in future versions.\n");
|
||||
fprintf(fp, "Please use status or json options instead.\n\n");
|
||||
|
||||
indx++;
|
||||
client = client->next;
|
||||
}
|
||||
@@ -645,40 +688,83 @@ ndsctl_clients(FILE *fp)
|
||||
}
|
||||
|
||||
static void
|
||||
ndsctl_json_client(FILE *fp, const t_client *client, time_t now)
|
||||
ndsctl_json_client(FILE *fp, const t_client *client, time_t now, char *indent)
|
||||
{
|
||||
unsigned long int durationsecs;
|
||||
unsigned long long int download_bytes, upload_bytes;
|
||||
|
||||
fprintf(fp, "\"id\":\"%d\",\n", client->id);
|
||||
fprintf(fp, "\"ip\":\"%s\",\n", client->ip);
|
||||
fprintf(fp, "\"mac\":\"%s\",\n", client->mac);
|
||||
fprintf(fp, "\"added\":\"%lld\",\n", (long long) client->session_start);
|
||||
fprintf(fp, "\"active\":\"%lld\",\n", (long long) client->counters.last_updated);
|
||||
fprintf(fp, " %s\"mac\":\"%s\",\n", indent, client->mac);
|
||||
fprintf(fp, " %s\"ip\":\"%s\",\n", indent, client->ip);
|
||||
fprintf(fp, " %s\"added\":\"%lld\",\n", indent, (long long) client->session_start);
|
||||
fprintf(fp, " %s\"active\":\"%lld\",\n", indent, (long long) client->counters.last_updated);
|
||||
|
||||
if (client->session_start) {
|
||||
fprintf(fp, "\"duration\":\"%lu\",\n", now - client->session_start);
|
||||
fprintf(fp, " %s\"duration\":\"%lu\",\n", indent, now - client->session_start);
|
||||
} else {
|
||||
fprintf(fp, "\"duration\":\"%lu\",\n", 0ul);
|
||||
fprintf(fp, " %s\"duration\":\"%lu\",\n", indent, 0ul);
|
||||
}
|
||||
fprintf(fp, "\"token\":\"%s\",\n", client->token ? client->token : "none");
|
||||
fprintf(fp, "\"state\":\"%s\",\n", fw_connection_state_as_string(client->fw_connection_state));
|
||||
fprintf(fp, " %s\"token\":\"%s\",\n", indent, client->token ? client->token : "none");
|
||||
fprintf(fp, " %s\"state\":\"%s\",\n", indent, fw_connection_state_as_string(client->fw_connection_state));
|
||||
|
||||
durationsecs = now - client->session_start;
|
||||
download_bytes = client->counters.incoming;
|
||||
upload_bytes = client->counters.outgoing;
|
||||
|
||||
fprintf(fp, "\"downloaded\":\"%llu\",\n", download_bytes / 1000);
|
||||
fprintf(fp, "\"avg_down_speed\":\"%.2f\",\n", ((double)download_bytes) / 125 / durationsecs);
|
||||
fprintf(fp, "\"uploaded\":\"%llu\",\n", upload_bytes / 1000);
|
||||
fprintf(fp, "\"avg_up_speed\":\"%.2f\"\n", ((double)upload_bytes)/ 125 / durationsecs);
|
||||
if (client->upload_rate == 0) {
|
||||
fprintf(fp, " %s\"upload_rate_limit\":\"null\",\n", indent);
|
||||
} else {
|
||||
fprintf(fp, " %s\"upload_rate_limit\":\"%llu\",\n", indent, client->upload_rate);
|
||||
}
|
||||
|
||||
if (client->download_rate == 0) {
|
||||
fprintf(fp, " %s\"download_rate_limit\":\"null\",\n", indent);
|
||||
} else {
|
||||
fprintf(fp, " %s\"download_rate_limit\":\"%llu\",\n", indent, client->download_rate);
|
||||
}
|
||||
|
||||
if (client->upload_quota == 0) {
|
||||
fprintf(fp, " %s\"upload_quota\":\"null\",\n", indent);
|
||||
} else {
|
||||
fprintf(fp, " %s\"upload_quota\":\"%llu\",\n", indent, client->upload_quota);
|
||||
}
|
||||
|
||||
if (client->download_quota == 0) {
|
||||
fprintf(fp, " %s\"download_quota\":\"null\",\n", indent);
|
||||
} else {
|
||||
fprintf(fp, " %s\"download_quota\":\"%llu\",\n", indent, client->download_quota);
|
||||
}
|
||||
|
||||
// prevent divison by 0
|
||||
if (durationsecs < 1) {
|
||||
durationsecs = 1;
|
||||
}
|
||||
|
||||
fprintf(fp, " %s\"upload_this_session\":\"%llu\",\n",
|
||||
indent,
|
||||
(upload_bytes / 1000)
|
||||
);
|
||||
|
||||
fprintf(fp, " %s\"upload_session_avg\":\"%.2f\",\n",
|
||||
indent,
|
||||
(double)upload_bytes / 125 / durationsecs
|
||||
);
|
||||
|
||||
fprintf(fp, " %s\"download_this_session\":\"%llu\",\n",
|
||||
indent,
|
||||
(download_bytes / 1000)
|
||||
);
|
||||
|
||||
fprintf(fp, " %s\"download_session_avg\":\"%.2f\"\n",
|
||||
indent,
|
||||
(double)download_bytes / 125 / durationsecs
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
ndsctl_json_one(FILE *fp, const char *arg)
|
||||
ndsctl_json_one(FILE *fp, const char *arg, char *indent)
|
||||
{
|
||||
t_client *client;
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
// Update the client's counters so info is current
|
||||
@@ -690,7 +776,7 @@ ndsctl_json_one(FILE *fp, const char *arg)
|
||||
|
||||
if (client) {
|
||||
fprintf(fp, "{\n");
|
||||
ndsctl_json_client(fp, client, now);
|
||||
ndsctl_json_client(fp, client, now, indent);
|
||||
fprintf(fp, "}\n");
|
||||
} else {
|
||||
fprintf(fp, "{}\n");
|
||||
@@ -700,7 +786,7 @@ ndsctl_json_one(FILE *fp, const char *arg)
|
||||
}
|
||||
|
||||
static void
|
||||
ndsctl_json_all(FILE *fp)
|
||||
ndsctl_json_all(FILE *fp, char *indent)
|
||||
{
|
||||
t_client *client;
|
||||
time_t now;
|
||||
@@ -717,25 +803,25 @@ ndsctl_json_all(FILE *fp)
|
||||
|
||||
LOCK_CLIENT_LIST();
|
||||
|
||||
fprintf(fp, "{\n\"client_list_length\": \"%d\",\n", get_client_list_length());
|
||||
fprintf(fp, "{\n \"client_list_length\":\"%d\",\n", get_client_list_length());
|
||||
|
||||
client = client_get_first_client();
|
||||
|
||||
fprintf(fp, "\"clients\":{\n");
|
||||
fprintf(fp, " \"clients\":{\n");
|
||||
|
||||
while (client != NULL) {
|
||||
fprintf(fp, "\"%s\":{\n", client->mac);
|
||||
ndsctl_json_client(fp, client, now);
|
||||
fprintf(fp, "%s\"%s\":{\n", indent, client->mac);
|
||||
ndsctl_json_client(fp, client, now, indent);
|
||||
|
||||
client = client->next;
|
||||
if (client) {
|
||||
fprintf(fp, "},\n");
|
||||
fprintf(fp, "%s},\n", indent);
|
||||
} else {
|
||||
fprintf(fp, "}\n");
|
||||
fprintf(fp, "%s}\n", indent);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "}\n}\n");
|
||||
fprintf(fp, " }\n");
|
||||
|
||||
UNLOCK_CLIENT_LIST();
|
||||
|
||||
@@ -748,32 +834,36 @@ ndsctl_json_all(FILE *fp)
|
||||
}
|
||||
|
||||
// output the count of trusted macs and list them in json array format
|
||||
fprintf(fp, "{\n\"trusted_list_length\": \"%d\",\n", count);
|
||||
fprintf(fp, "\"trusted\":[\n");
|
||||
fprintf(fp, " \"trusted_list_length\":\"%d\",\n", count);
|
||||
fprintf(fp, " \"trusted\":[\n");
|
||||
|
||||
for (trust_mac = config->trustedmaclist; trust_mac != NULL; trust_mac = trust_mac->next) {
|
||||
|
||||
if (count > 1) {
|
||||
fprintf(fp, "\"%s\",\n", trust_mac->mac);
|
||||
fprintf(fp, " \"%s\",\n", trust_mac->mac);
|
||||
count--;
|
||||
} else {
|
||||
fprintf(fp, "\"%s\"\n", trust_mac->mac);
|
||||
fprintf(fp, " \"%s\"\n", trust_mac->mac);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "]\n}\n");
|
||||
fprintf(fp, " ]\n");
|
||||
}
|
||||
fprintf(fp, "}\n");
|
||||
}
|
||||
|
||||
void
|
||||
ndsctl_json(FILE *fp, const char *arg)
|
||||
{
|
||||
char indent[5] = {0};
|
||||
//if (arg && strlen(arg)) {
|
||||
debug(LOG_DEBUG, "arg [%s %d]", arg, strlen(arg));
|
||||
if (strlen(arg) > 6) {
|
||||
ndsctl_json_one(fp, arg);
|
||||
//snprintf(indent, sizeof(indent), "%s", "");
|
||||
ndsctl_json_one(fp, arg, indent);
|
||||
} else {
|
||||
ndsctl_json_all(fp);
|
||||
snprintf(indent, sizeof(indent), "%s", " ");
|
||||
ndsctl_json_all(fp, indent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user