Added connect/disconnect/getopt/setopt and handle to xmldb API; Added datastore 'text'; Moved apps/dbctrl to datastore/
This commit is contained in:
parent
85af4342dc
commit
d26a801bc0
25 changed files with 1501 additions and 912 deletions
|
|
@ -43,7 +43,6 @@ SHELL = /bin/sh
|
|||
|
||||
SUBDIRS = backend
|
||||
SUBDIRS += cli
|
||||
SUBDIRS += dbctrl
|
||||
SUBDIRS += netconf
|
||||
ifeq ($(with_restconf),yes)
|
||||
SUBDIRS += restconf
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* Prototypes
|
||||
* not exported.
|
||||
*/
|
||||
/* backend handles */
|
||||
/* backend handles. Defined in clixon_backend_handle.c */
|
||||
clicon_handle backend_handle_init(void);
|
||||
|
||||
int backend_handle_exit(clicon_handle h);
|
||||
|
|
|
|||
|
|
@ -254,19 +254,20 @@ server_socket(clicon_handle h)
|
|||
* log event.
|
||||
*/
|
||||
static int
|
||||
config_log_cb(int level, char *msg, void *arg)
|
||||
config_log_cb(int level,
|
||||
char *msg,
|
||||
void *arg)
|
||||
{
|
||||
int retval = -1;
|
||||
size_t n;
|
||||
char *ptr;
|
||||
char *nptr;
|
||||
char *newmsg = NULL;
|
||||
int retval = -1;
|
||||
char *ptr;
|
||||
char *nptr;
|
||||
char *newmsg = NULL;
|
||||
|
||||
/* backend_notify() will go through all clients and see if any has registered "CLICON",
|
||||
and if so make a clicon_proto notify message to those clients. */
|
||||
|
||||
|
||||
/* Sanitize '%' into "%%" to prevent segvfaults in vsnprintf later.
|
||||
/* backend_notify() will go through all clients and see if any has
|
||||
registered "CLICON", and if so make a clicon_proto notify message to
|
||||
those clients.
|
||||
Sanitize '%' into "%%" to prevent segvfaults in vsnprintf later.
|
||||
At this stage all formatting is already done */
|
||||
n = 0;
|
||||
for(ptr=msg; *ptr; ptr++)
|
||||
|
|
@ -281,7 +282,6 @@ config_log_cb(int level, char *msg, void *arg)
|
|||
if (*ptr == '%')
|
||||
*nptr++ = '%';
|
||||
}
|
||||
|
||||
retval = backend_notify(arg, "CLICON", level, newmsg);
|
||||
free(newmsg);
|
||||
|
||||
|
|
@ -509,13 +509,21 @@ main(int argc, char **argv)
|
|||
clicon_log(LOG_ERR, "No xmldb plugin given (specify option CLICON_XMLDB_PLUGIN).\n");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_plugin_load(xmldb_plugin) < 0)
|
||||
if (xmldb_plugin_load(h, xmldb_plugin) < 0)
|
||||
goto done;
|
||||
/* Connect to plugin to get a handle */
|
||||
if (xmldb_connect(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Parse db spec file */
|
||||
if (yang_spec_main(h, stdout, printspec) < 0)
|
||||
goto done;
|
||||
|
||||
/* Set options: database dir aqnd yangspec (could be hidden in connect?)*/
|
||||
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)
|
||||
goto done;
|
||||
if (xmldb_setopt(h, "yangspec", clicon_dbspec_yang(h)) < 0)
|
||||
goto done;
|
||||
|
||||
/* First check for startup config
|
||||
XXX the options below have become out-of-hand.
|
||||
Too complex, need to simplify*/
|
||||
|
|
|
|||
|
|
@ -75,14 +75,21 @@
|
|||
* This file should only contain access functions for the _specific_
|
||||
* entries in the struct below.
|
||||
*/
|
||||
/*! Backend specific handle added to header CLICON handle
|
||||
* This file should only contain access functions for the _specific_
|
||||
* entries in the struct below.
|
||||
* @note The top part must be equivalent to struct clicon_handle in clixon_handle.c
|
||||
* @see struct clicon_handle, struct cli_handle
|
||||
*/
|
||||
struct backend_handle {
|
||||
int cb_magic; /* magic (HDR)*/
|
||||
clicon_hash_t *cb_copt; /* clicon option list (HDR) */
|
||||
clicon_hash_t *cb_data; /* internal clicon data (HDR) */
|
||||
int bh_magic; /* magic (HDR)*/
|
||||
clicon_hash_t *bh_copt; /* clicon option list (HDR) */
|
||||
clicon_hash_t *bh_data; /* internal clicon data (HDR) */
|
||||
void *bh_xmldb; /* XMLDB storage handle, uie xmldb_handle */
|
||||
/* ------ end of common handle ------ */
|
||||
struct client_entry *cb_ce_list; /* The client list */
|
||||
int cb_ce_nr; /* Number of clients, just increment */
|
||||
struct handle_subscription *cb_subscription; /* Event subscription list */
|
||||
struct client_entry *bh_ce_list; /* The client list */
|
||||
int bh_ce_nr; /* Number of clients, just increment */
|
||||
struct handle_subscription *bh_subscription; /* Event subscription list */
|
||||
};
|
||||
|
||||
/*! Creates and returns a clicon config handle for other CLICON API calls
|
||||
|
|
@ -257,11 +264,17 @@ backend_notify_xml(clicon_handle h,
|
|||
|
||||
}
|
||||
|
||||
/*! Add new client, typically frontend such as cli, netconf, restconf
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] addr Address of client
|
||||
* @retval ce Client entry
|
||||
* @retval NULL Error
|
||||
*/
|
||||
struct client_entry *
|
||||
backend_client_add(clicon_handle h,
|
||||
struct sockaddr *addr)
|
||||
{
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
struct client_entry *ce;
|
||||
|
||||
if ((ce = (struct client_entry *)malloc(sizeof(*ce))) == NULL){
|
||||
|
|
@ -269,24 +282,28 @@ backend_client_add(clicon_handle h,
|
|||
return NULL;
|
||||
}
|
||||
memset(ce, 0, sizeof(*ce));
|
||||
ce->ce_nr = cb->cb_ce_nr++;
|
||||
ce->ce_nr = bh->bh_ce_nr++;
|
||||
memcpy(&ce->ce_addr, addr, sizeof(*addr));
|
||||
ce->ce_next = cb->cb_ce_list;
|
||||
cb->cb_ce_list = ce;
|
||||
ce->ce_next = bh->bh_ce_list;
|
||||
bh->bh_ce_list = ce;
|
||||
return ce;
|
||||
}
|
||||
|
||||
/*! Return client list
|
||||
* @param[in] h Clicon handle
|
||||
* @retval ce_list Client entry list (all sessions)
|
||||
*/
|
||||
struct client_entry *
|
||||
backend_client_list(clicon_handle h)
|
||||
{
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
|
||||
return cb->cb_ce_list;
|
||||
return bh->bh_ce_list;
|
||||
}
|
||||
|
||||
/*! Actually remove client from client list
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ce Client hadnle
|
||||
* @param[in] ce Client handle
|
||||
* @see backend_client_rm which is more high-level
|
||||
*/
|
||||
int
|
||||
|
|
@ -295,9 +312,9 @@ backend_client_delete(clicon_handle h,
|
|||
{
|
||||
struct client_entry *c;
|
||||
struct client_entry **ce_prev;
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
|
||||
ce_prev = &cb->cb_ce_list;
|
||||
ce_prev = &bh->bh_ce_list;
|
||||
for (c = *ce_prev; c; c = c->ce_next){
|
||||
if (c == ce){
|
||||
*ce_prev = c->ce_next;
|
||||
|
|
@ -328,7 +345,7 @@ subscription_add(clicon_handle h,
|
|||
subscription_fn_t fn,
|
||||
void *arg)
|
||||
{
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
struct handle_subscription *hs = NULL;
|
||||
|
||||
if ((hs = malloc(sizeof(*hs))) == NULL){
|
||||
|
|
@ -339,10 +356,10 @@ subscription_add(clicon_handle h,
|
|||
hs->hs_stream = strdup(stream);
|
||||
hs->hs_format = format;
|
||||
hs->hs_filter = filter?strdup(filter):NULL;
|
||||
hs->hs_next = cb->cb_subscription;
|
||||
hs->hs_next = bh->bh_subscription;
|
||||
hs->hs_fn = fn;
|
||||
hs->hs_arg = arg;
|
||||
cb->cb_subscription = hs;
|
||||
bh->bh_subscription = hs;
|
||||
done:
|
||||
return hs;
|
||||
}
|
||||
|
|
@ -362,11 +379,11 @@ subscription_delete(clicon_handle h,
|
|||
subscription_fn_t fn,
|
||||
void *arg)
|
||||
{
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
struct handle_subscription *hs;
|
||||
struct handle_subscription **hs_prev;
|
||||
|
||||
hs_prev = &cb->cb_subscription; /* this points to stack and is not real backpointer */
|
||||
hs_prev = &bh->bh_subscription; /* this points to stack and is not real backpointer */
|
||||
for (hs = *hs_prev; hs; hs = hs->hs_next){
|
||||
/* XXX arg == hs->hs_arg */
|
||||
if (strcmp(hs->hs_stream, stream)==0 && hs->hs_fn == fn){
|
||||
|
|
@ -404,15 +421,16 @@ struct handle_subscription *
|
|||
subscription_each(clicon_handle h,
|
||||
struct handle_subscription *hprev)
|
||||
{
|
||||
struct backend_handle *cb = handle(h);
|
||||
struct backend_handle *bh = handle(h);
|
||||
struct handle_subscription *hs = NULL;
|
||||
|
||||
if (hprev)
|
||||
hs = hprev->hs_next;
|
||||
else
|
||||
hs = cb->cb_subscription;
|
||||
hs = bh->bh_subscription;
|
||||
return hs;
|
||||
}
|
||||
|
||||
/* Database dependency description */
|
||||
struct backend_netconf_reg {
|
||||
qelem_t nr_qelem; /* List header */
|
||||
|
|
@ -456,10 +474,9 @@ catch:
|
|||
/*! See if there is any callback registered for this tag
|
||||
*
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] xn Sub-tree (under xorig) at child of rpc: <rpc><xn></rpc>.
|
||||
* @param[out] cb Output xml stream. For reply
|
||||
* @param[out] cb_err Error xml stream. For error reply
|
||||
* @param[out] xret Return XML, error or OK
|
||||
* @param[in] xe Sub-tree (under xorig) at child of rpc: <rpc><xn></rpc>.
|
||||
* @param[in] ce Client (session) entry
|
||||
* @param[out] cbret Return XML, error or OK as cbuf
|
||||
*
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK, not found handler.
|
||||
|
|
|
|||
|
|
@ -69,17 +69,17 @@
|
|||
#define handle(h) (assert(clicon_handle_check(h)==0),(struct cli_handle *)(h))
|
||||
#define cligen(h) (handle(h)->cl_cligen)
|
||||
|
||||
/*
|
||||
* cli_handle
|
||||
* first part of this is header, same for clicon_handle and config_handle.
|
||||
* Access functions for common fields are found in clicon lib: clicon_options.[ch]
|
||||
/*! CLI specific handle added to header CLICON handle
|
||||
* This file should only contain access functions for the _specific_
|
||||
* entries in the struct below.
|
||||
* @note The top part must be equivalent to struct clicon_handle in clixon_handle.c
|
||||
* @see struct clicon_handle, struct backend_handle
|
||||
*/
|
||||
struct cli_handle {
|
||||
int cl_magic; /* magic (HDR)*/
|
||||
clicon_hash_t *cl_copt; /* clicon option list (HDR) */
|
||||
clicon_hash_t *cl_data; /* internal clicon data (HDR) */
|
||||
void *cl_xmldb; /* XMLDB storage handle, uie xmldb_handle */
|
||||
/* ------ end of common handle ------ */
|
||||
cligen_handle cl_cligen; /* cligen handle */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
#
|
||||
# Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||
#
|
||||
# This file is part of CLIXON
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# the GNU General Public License Version 3 or later (the "GPL"),
|
||||
# in which case the provisions of the GPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL, and not to allow others to
|
||||
# use your version of this file under the terms of Apache License version 2,
|
||||
# indicate your decision by deleting the provisions above and replace them with
|
||||
# the notice and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the Apache License version 2 or the GPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
#
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
|
||||
SH_SUFFIX = @SH_SUFFIX@
|
||||
CLIXON_MAJOR = @CLIXON_VERSION_MAJOR@
|
||||
CLIXON_MINOR = @CLIXON_VERSION_MINOR@
|
||||
|
||||
# Use this clixon lib for linking
|
||||
CLIXON_LIB = libclixon.so.$(CLIXON_MAJOR).$(CLIXON_MINOR)
|
||||
|
||||
# For dependency
|
||||
LIBDEPS = $(top_srcdir)/lib/src/$(CLIXON_LIB)
|
||||
|
||||
LIBS = -L$(top_srcdir)/lib/src @LIBS@ -l:$(CLIXON_LIB)
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
|
||||
INCLUDES = -I. -I$(top_srcdir)/lib/src -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir) @INCLUDES@
|
||||
|
||||
SRC =
|
||||
|
||||
OBJS = $(SRC:.c=.o)
|
||||
|
||||
APPSRC = dbctrl_main.c
|
||||
APPOBJ = $(APPSRC:.c=.o)
|
||||
APPL = clixon_dbctrl
|
||||
|
||||
all: $(APPL)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *.core $(APPL) $(APPOBJ)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *~ .depend
|
||||
|
||||
# Put demon in bin
|
||||
# Put other executables in libexec/
|
||||
# Also create a libexec/ directory for writeable/temporary files.
|
||||
# Put config file in etc/
|
||||
install: $(APPL)
|
||||
install -d $(DESTDIR)$(bindir)
|
||||
install $(APPL) $(DESTDIR)$(bindir)
|
||||
|
||||
install-include:
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/$(APPL)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(INCLUDES) -D__PROGRAM__=\"$(APPL)\" $(CPPFLAGS) $(CFLAGS) -c $<
|
||||
|
||||
$(APPL) : $(APPOBJ) $(OBJS) $(LIBDEPS)
|
||||
$(CC) $(LDFLAGS) $(APPOBJ) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
TAGS:
|
||||
find . -name '*.[chyl]' -print | etags -
|
||||
|
||||
depend:
|
||||
$(CC) $(DEPENDFLAGS) @DEFS@ $(INCLUDES) $(CFLAGS) -MM $(SRC) $(APPSRC) > .depend
|
||||
|
||||
#include .depend
|
||||
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
the GNU General Public License Version 3 or later (the "GPL"),
|
||||
in which case the provisions of the GPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of the GPL, and not to allow others to
|
||||
use your version of this file under the terms of Apache License version 2,
|
||||
indicate your decision by deleting the provisions above and replace them with
|
||||
the notice and other provisions required by the GPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the Apache License version 2 or the GPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
||||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define DBCTRL_OPTS "hDSd:pbn:r:m:Zi"
|
||||
|
||||
/*
|
||||
* remove_entry
|
||||
*/
|
||||
static int
|
||||
remove_entry(char *dbname, char *key)
|
||||
{
|
||||
#ifdef NOTYET /* This assumes direct access to database */
|
||||
return db_del(dbname, key);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! usage
|
||||
*/
|
||||
static void
|
||||
usage(char *argv0)
|
||||
{
|
||||
fprintf(stderr, "usage:%s\n"
|
||||
"where options are\n"
|
||||
"\t-h\t\tHelp\n"
|
||||
"\t-D\t\tDebug\n"
|
||||
"\t-S\t\tLog on syslog\n"
|
||||
"\t-d <db>\t\tDatabase name (default: running)\n"
|
||||
"\t-p\t\tDump database on stdout\n"
|
||||
"\t-b\t\tBrief output, just print keys. Combine with -p or -m\n"
|
||||
"\t-n \"<key> <val>\" Add database entry\n"
|
||||
"\t-r <key>\tRemove database entry\n"
|
||||
"\t-m <regexp key>\tMatch regexp key in database\n"
|
||||
"\t-Z\t\tDelete database\n"
|
||||
"\t-i\t\tInit database\n",
|
||||
argv0
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char c;
|
||||
int zapdb;
|
||||
int initdb;
|
||||
int dumpdb;
|
||||
int addent;
|
||||
int rment;
|
||||
char *matchkey = NULL;
|
||||
char *addstr;
|
||||
char rmkey[MAXPATHLEN];
|
||||
int brief;
|
||||
char db[MAXPATHLEN] = {0,};
|
||||
int use_syslog;
|
||||
clicon_handle h;
|
||||
|
||||
/* In the startup, logs to stderr & debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_STDERR);
|
||||
|
||||
/* Defaults */
|
||||
zapdb = 0;
|
||||
initdb = 0;
|
||||
dumpdb = 0;
|
||||
addent = 0;
|
||||
rment = 0;
|
||||
brief = 0;
|
||||
use_syslog = 0;
|
||||
addstr = NULL;
|
||||
memcpy(db, "running", strlen("running")+1);
|
||||
memset(rmkey, '\0', sizeof(rmkey));
|
||||
|
||||
if ((h = clicon_handle_init()) == NULL)
|
||||
goto done;
|
||||
/* getopt in two steps, first find config-file before over-riding options. */
|
||||
while ((c = getopt(argc, argv, DBCTRL_OPTS)) != -1)
|
||||
switch (c) {
|
||||
case '?' :
|
||||
case 'h' : /* help */
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'D' : /* debug */
|
||||
debug = 1;
|
||||
break;
|
||||
case 'S': /* Log on syslog */
|
||||
use_syslog = 1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Logs, error and debug to stderr or syslog, set debug level
|
||||
*/
|
||||
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO,
|
||||
use_syslog?CLICON_LOG_SYSLOG:CLICON_LOG_STDERR);
|
||||
clicon_debug_init(debug, NULL);
|
||||
|
||||
|
||||
/* Now rest of options */
|
||||
optind = 1;
|
||||
while ((c = getopt(argc, argv, DBCTRL_OPTS)) != -1)
|
||||
switch (c) {
|
||||
case 'Z': /* Zap database */
|
||||
zapdb++;
|
||||
break;
|
||||
case 'i': /* Init database */
|
||||
initdb++;
|
||||
break;
|
||||
case 'p': /* Dump/print database */
|
||||
dumpdb++;
|
||||
break;
|
||||
case 'b': /* Dump/print/match database brief (combone w -p or -m) */
|
||||
brief++;
|
||||
break;
|
||||
case 'd': /* db either db filename or symbolic: running|candidate */
|
||||
if (!optarg || sscanf(optarg, "%s", db) != 1)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'n': /* add database entry */
|
||||
if (!optarg || !strlen(optarg) || (addstr = strdup(optarg)) == NULL)
|
||||
usage(argv[0]);
|
||||
/* XXX addign both key and value, for now only key */
|
||||
addent++;
|
||||
break;
|
||||
case 'r':
|
||||
if (!optarg || sscanf(optarg, "%s", rmkey) != 1)
|
||||
usage(argv[0]);
|
||||
rment++;
|
||||
break;
|
||||
case 'm':
|
||||
if (!optarg || !strlen(optarg) || (matchkey = strdup(optarg)) == NULL)
|
||||
usage(argv[0]);
|
||||
dumpdb++;
|
||||
break;
|
||||
case 'D': /* Processed earlier, ignore now. */
|
||||
case 'S':
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (*db == '\0'){
|
||||
clicon_err(OE_FATAL, 0, "database not specified (with -d <db>): %s");
|
||||
goto done;
|
||||
}
|
||||
if (dumpdb){
|
||||
/* Here db must be local file-path */
|
||||
if (xmldb_dump(stdout, db, matchkey)) {
|
||||
fprintf(stderr, "Match error\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (addent){ /* add entry */
|
||||
cxobj *xml = NULL;
|
||||
|
||||
if (clicon_xml_parse(&xml, "<config>%s</config>", addstr) < 0)
|
||||
goto done;
|
||||
if (xmldb_put(h, db, OP_REPLACE, NULL, xml) < 0)
|
||||
goto done;
|
||||
if (xml)
|
||||
xml_free(xml);
|
||||
|
||||
}
|
||||
if (rment)
|
||||
if (remove_entry(db, rmkey) < 0)
|
||||
goto done;
|
||||
if (zapdb) /* remove databases */
|
||||
if (xmldb_delete(h, db) < 0){
|
||||
clicon_err(OE_FATAL, errno, "delete %s", db);
|
||||
goto done;
|
||||
}
|
||||
if (initdb)
|
||||
if (xmldb_init(h, db) < 0)
|
||||
goto done;
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue