mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
output: add more items to mustach tags
Base level printing; localstime, number of ranges and shared networks, project version, and file paths and time stamps. Also print error and stop template processing when unknown tag is encountered. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
d24313d25a
commit
ff3d9523e6
4 changed files with 154 additions and 34 deletions
|
|
@ -14,7 +14,7 @@ Subnets:{{#subnets}}
|
||||||
backup_percent: {{backup_percent}}
|
backup_percent: {{backup_percent}}
|
||||||
status: {{status}}
|
status: {{status}}
|
||||||
gettimeofday: {{gettimeofday}}
|
gettimeofday: {{gettimeofday}}
|
||||||
lease_file_mtime: {{lease_file_mtime}}
|
lease_file_epoch_mtime: {{lease_file_epoch_mtime}}
|
||||||
{{/subnets}}
|
{{/subnets}}
|
||||||
|
|
||||||
Shared-networks:{{#shared-networks}}
|
Shared-networks:{{#shared-networks}}
|
||||||
|
|
@ -30,7 +30,7 @@ Shared-networks:{{#shared-networks}}
|
||||||
backup_percent: {{backup_percent}}
|
backup_percent: {{backup_percent}}
|
||||||
status: {{status}}
|
status: {{status}}
|
||||||
gettimeofday: {{gettimeofday}}
|
gettimeofday: {{gettimeofday}}
|
||||||
lease_file_mtime: {{lease_file_mtime}}
|
lease_file_epoch_mtime: {{lease_file_epoch_mtime}}
|
||||||
{{/shared-networks}}
|
{{/shared-networks}}
|
||||||
|
|
||||||
Summary:{{#summary}}
|
Summary:{{#summary}}
|
||||||
|
|
@ -46,5 +46,22 @@ Summary:{{#summary}}
|
||||||
backup_percent: {{backup_percent}}
|
backup_percent: {{backup_percent}}
|
||||||
status: {{status}}
|
status: {{status}}
|
||||||
gettimeofday: {{gettimeofday}}
|
gettimeofday: {{gettimeofday}}
|
||||||
lease_file_mtime: {{lease_file_mtime}}
|
lease_file_epoch_mtime: {{lease_file_epoch_mtime}}
|
||||||
{{/summary}}
|
{{/summary}}
|
||||||
|
|
||||||
|
localtime: {{localtime}}
|
||||||
|
number_of_ranges: {{number_of_ranges}}
|
||||||
|
number_of_shared_networks: {{number_of_shared_networks}}
|
||||||
|
version: {{version}}
|
||||||
|
|
||||||
|
conf_file_path: {{conf_file_path}}
|
||||||
|
conf_file_local_mtime: {{conf_file_local_mtime}}
|
||||||
|
conf_file_epoch_mtime: {{conf_file_epoch_mtime}}
|
||||||
|
|
||||||
|
lease_file_path: {{lease_file_path}}
|
||||||
|
lease_file_local_mtime: {{lease_file_local_mtime}}
|
||||||
|
lease_file_epoch_mtime: {{lease_file_epoch_mtime}}
|
||||||
|
|
||||||
|
template_file_path: {{template_file_path}}
|
||||||
|
template_file_local_mtime: {{template_file_local_mtime}}
|
||||||
|
template_file_epoch_mtime: {{template_file_epoch_mtime}}
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "close-stream.h"
|
#include "close-stream.h"
|
||||||
#include "dhcpd-pools.h"
|
#include "dhcpd-pools.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "mustach.h"
|
#include "mustach.h"
|
||||||
|
#include "strftime.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
/*! \struct expl
|
/*! \struct expl
|
||||||
|
|
@ -67,14 +69,109 @@ struct expl {
|
||||||
static int must_enter(void *closure, const char *name);
|
static int must_enter(void *closure, const char *name);
|
||||||
static int must_leave(void *closure);
|
static int must_leave(void *closure);
|
||||||
|
|
||||||
/*! \brief This function can be called when mustach template is invalid.
|
static void dp_time_tool(FILE *file, const char *path, int epoch)
|
||||||
* In such case either must_put_range or must_put_shnet is tried to call before
|
|
||||||
* must_enter. */
|
|
||||||
static int must_put_err(void *closure __attribute__ ((unused)),
|
|
||||||
const char *name __attribute__ ((unused)),
|
|
||||||
int escape __attribute__ ((unused)), FILE *file __attribute__ ((unused)))
|
|
||||||
{
|
{
|
||||||
return MUSTACH_ERROR_SYSTEM;
|
time_t t;
|
||||||
|
|
||||||
|
/* a file or now */
|
||||||
|
if (path) {
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
stat(path, &st);
|
||||||
|
t = st.st_mtime;
|
||||||
|
} else
|
||||||
|
t = time(NULL);
|
||||||
|
/* epoc or iso time stamp */
|
||||||
|
if (epoch)
|
||||||
|
fprintf(file, "%ld", t);
|
||||||
|
else {
|
||||||
|
char time_stamp[64];
|
||||||
|
struct tm tm;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
localtime_r(&t, &tm);
|
||||||
|
len = snprintf(time_stamp, sizeof(time_stamp), "%4d-%.2d-%.2dT%02d:%02d:%02d",
|
||||||
|
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||||
|
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||||
|
strftime(time_stamp + len, sizeof(time_stamp) - len, "%z", &tm);
|
||||||
|
fprintf(file, "%s", time_stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Template base level tag parser and printer. */
|
||||||
|
static int must_put_base(void *closure, const char *name, int escape
|
||||||
|
__attribute__ ((unused)), FILE *file)
|
||||||
|
{
|
||||||
|
struct expl *e = closure;
|
||||||
|
|
||||||
|
if (!strcmp(name, "localtime")) {
|
||||||
|
dp_time_tool(file, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "number_of_ranges")) {
|
||||||
|
fprintf(file, "%u", e->state->num_ranges);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "number_of_shared_networks")) {
|
||||||
|
static uint32_t num = 0xffffffff;
|
||||||
|
|
||||||
|
if (num == 0xffffffff) {
|
||||||
|
/* Use of static num ensures this is done only once. */
|
||||||
|
struct shared_network_t *shared_p;
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (shared_p = e->state->shared_net_root->next; shared_p;
|
||||||
|
shared_p = shared_p->next)
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
fprintf(file, "%u", num);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "version")) {
|
||||||
|
fprintf(file, "%s", PACKAGE_VERSION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* lease file */
|
||||||
|
if (!strcmp(name, "lease_file_path")) {
|
||||||
|
fprintf(file, "%s", e->state->dhcpdlease_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "lease_file_local_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->dhcpdlease_file, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "lease_file_epoch_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->dhcpdlease_file, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* conf file */
|
||||||
|
if (!strcmp(name, "conf_file_path")) {
|
||||||
|
fprintf(file, "%s", e->state->dhcpdconf_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "conf_file_local_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->dhcpdconf_file, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "conf_file_epoch_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->dhcpdconf_file, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* template file */
|
||||||
|
if (!strcmp(name, "template_file_path")) {
|
||||||
|
fprintf(file, "%s", e->state->mustach_template);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "template_file_local_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->mustach_template, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "template_file_epoch_mtime")) {
|
||||||
|
dp_time_tool(file, e->state->mustach_template, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
error(EXIT_FAILURE, 0, "mustach_dhcpd_pools: fmustach: unexpected tag: %s", name);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \struct mustach_itf
|
/*! \struct mustach_itf
|
||||||
|
|
@ -82,7 +179,7 @@ static int must_put_err(void *closure __attribute__ ((unused)),
|
||||||
static struct mustach_itf itf = {
|
static struct mustach_itf itf = {
|
||||||
.start = NULL,
|
.start = NULL,
|
||||||
.enter = must_enter,
|
.enter = must_enter,
|
||||||
.put = must_put_err,
|
.put = must_put_base,
|
||||||
.next = NULL,
|
.next = NULL,
|
||||||
.leave = must_leave
|
.leave = must_leave
|
||||||
};
|
};
|
||||||
|
|
@ -153,20 +250,15 @@ static int must_put_range(void *closure, const char *name, int escape
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "gettimeofday")) {
|
if (!strcmp(name, "gettimeofday")) {
|
||||||
struct timeval tp;
|
dp_time_tool(file, NULL, 1);
|
||||||
|
|
||||||
gettimeofday(&tp, NULL);
|
|
||||||
fprintf(file, "%ld", tp.tv_sec);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "lease_file_mtime")) {
|
if (!strcmp(name, "lease_file_epoch_mtime")) {
|
||||||
struct stat st;
|
dp_time_tool(file, e->state->dhcpdlease_file, 1);
|
||||||
|
|
||||||
stat(e->state->dhcpdlease_file, &st);
|
|
||||||
fprintf(file, "%ld", st.st_mtime);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
error(EXIT_FAILURE, 0, "mustach_dhcpd_pools: fmustach: unexpected tag: %s", name);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Mustach shared networks aka {{#shared-networks}} tag parser and printer. */
|
/*! \brief Mustach shared networks aka {{#shared-networks}} tag parser and printer. */
|
||||||
|
|
@ -222,20 +314,15 @@ static int must_put_shnet(void *closure, const char *name, int escape
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "gettimeofday")) {
|
if (!strcmp(name, "gettimeofday")) {
|
||||||
struct timeval tp;
|
dp_time_tool(file, NULL, 1);
|
||||||
|
|
||||||
gettimeofday(&tp, NULL);
|
|
||||||
fprintf(file, "%ld", tp.tv_sec);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "lease_file_mtime")) {
|
if (!strcmp(name, "lease_file_epoch_mtime")) {
|
||||||
struct stat st;
|
dp_time_tool(file, e->state->dhcpdlease_file, 1);
|
||||||
|
|
||||||
stat(e->state->dhcpdlease_file, &st);
|
|
||||||
fprintf(file, "%ld", st.st_mtime);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
error(EXIT_FAILURE, 0, "mustach_dhcpd_pools: fmustach: unexpected tag: %s", name);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief A function to move to next range when {{/subnets}} is encountered. */
|
/*! \brief A function to move to next range when {{/subnets}} is encountered. */
|
||||||
|
|
@ -302,7 +389,8 @@ static int must_enter(void *closure, const char *name)
|
||||||
shnet_output_helper(e->state, &e->oh, e->shnet_p);
|
shnet_output_helper(e->state, &e->oh, e->shnet_p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
error(EXIT_FAILURE, 0, "mustach_dhcpd_pools: fmustach: unexpected tag: %s", name);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Function that is called when all elements within a print loop are outputed. */
|
/*! \brief Function that is called when all elements within a print loop are outputed. */
|
||||||
|
|
@ -312,6 +400,7 @@ static int must_leave(void *closure)
|
||||||
|
|
||||||
e->shnet_p = e->state->shared_net_root;
|
e->shnet_p = e->state->shared_net_root;
|
||||||
e->range_p = e->state->ranges;
|
e->range_p = e->state->ranges;
|
||||||
|
itf.put = must_put_base;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,12 @@ Summary:
|
||||||
backup_percent: 2
|
backup_percent: 2
|
||||||
status: 0
|
status: 0
|
||||||
|
|
||||||
|
|
||||||
|
number_of_ranges: 5
|
||||||
|
number_of_shared_networks: 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- skip ok ---
|
--- skip ok ---
|
||||||
Subnets:
|
Subnets:
|
||||||
location: example1
|
location: example1
|
||||||
|
|
@ -189,3 +195,9 @@ Summary:
|
||||||
backup_percent: 2
|
backup_percent: 2
|
||||||
status: 0
|
status: 0
|
||||||
|
|
||||||
|
|
||||||
|
number_of_ranges: 5
|
||||||
|
number_of_shared_networks: 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,16 @@ if [ ! -d tests/outputs ]; then
|
||||||
mkdir tests/outputs
|
mkdir tests/outputs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
remove='/gettimeofday:/d; /^localtime:/d; /^conf_file_/d; /lease_file_/d; /^template_file_/d; /^version:/d'
|
||||||
|
|
||||||
dhcpd-pools -c $top_srcdir/samples/dhcpd.conf -l $top_srcdir/samples/dhcpd.leases \
|
dhcpd-pools -c $top_srcdir/samples/dhcpd.conf -l $top_srcdir/samples/dhcpd.leases \
|
||||||
--mustach $top_srcdir/samples/mustach.template |
|
--mustach $top_srcdir/samples/mustach.template |
|
||||||
sed '/gettimeofday:/d; /lease_file_mtime:/d' >| tests/outputs/$IAM
|
sed "$remove" >| tests/outputs/$IAM
|
||||||
|
|
||||||
echo "--- skip ok ---" >> tests/outputs/$IAM
|
echo "--- skip ok ---" >> tests/outputs/$IAM
|
||||||
dhcpd-pools -c $top_srcdir/samples/dhcpd.conf -l $top_srcdir/samples/dhcpd.leases \
|
dhcpd-pools -c $top_srcdir/samples/dhcpd.conf -l $top_srcdir/samples/dhcpd.leases \
|
||||||
--mustach $top_srcdir/samples/mustach.template --skip=ok --warning 44 |
|
--mustach $top_srcdir/samples/mustach.template --skip=ok --warning 44 |
|
||||||
sed '/gettimeofday:/d; /lease_file_mtime:/d' >> tests/outputs/$IAM
|
sed "$remove" >> tests/outputs/$IAM
|
||||||
|
|
||||||
diff -u $top_srcdir/tests/expected/$IAM tests/outputs/$IAM
|
diff -u $top_srcdir/tests/expected/$IAM tests/outputs/$IAM
|
||||||
exit $?
|
exit $?
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue