Created xmldb plugin api

This commit is contained in:
Olof hagsand 2017-04-09 22:53:48 +02:00
parent 4169bd8d30
commit f6b3e95100
39 changed files with 492 additions and 504 deletions

View file

@ -61,8 +61,7 @@ CPPFLAGS = @CPPFLAGS@
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \
clixon_chunk.c clixon_proc.c \
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c clixon_proc.c \
clixon_string.c clixon_handle.c \
clixon_xml.c clixon_xml_map.c clixon_file.c \
clixon_json.c clixon_yang.c clixon_yang_type.c \

View file

@ -1,789 +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 *****
*/
/* Error handling: dont use clicon_err, treat as unix system calls. That is,
ensure errno is set and return -1/NULL */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/types.h>
/* clicon */
#include "clixon_queue.h"
#include "clixon_chunk.h"
/*
* The chunk head array for the predefined chunk sizes.
*/
static chunk_head_t chunk_heads[CHUNK_HEADS];
/*
* Did we initialize the chunk heads yet?
*/
static int chunk_initialized = 0;
/*
* The pagesize of this system
*/
static int chunk_pagesz;
/*
* List of chunk groups
*/
static chunk_group_t *chunk_grp;
/*
* Hack to tell unchunk() not to remove chunk_group if empty
*/
static int dont_unchunk_group;
/*
* Initialize chunk library
*/
static void
chunk_initialize ()
{
int pgs;
register int idx;
chunk_pagesz = getpagesize();
bzero (&chunk_heads, sizeof (chunk_heads));
for (idx = 0; idx < CHUNK_HEADS; idx++) {
chunk_head_t *chead = &chunk_heads[idx];
/*
* Calculate the size of a block
*/
pgs = (0x01lu << (CHUNK_BASE + idx)) / chunk_pagesz;
if (pgs == 0)
pgs = 1;
chead->ch_blksz = pgs * chunk_pagesz;
/*
* Chunks per block is 1 for all size above a page. For sizes
* (including the chunk header) less than a page it's as many
* as fits
*/
chead->ch_nchkperblk = chead->ch_blksz / (0x01lu << (CHUNK_BASE + idx));
/*
* Size of each chunk is:
* (size + chnkhdr) * ncnkperblk = blksiz - blkhdr
*/
chead->ch_size =
(chead->ch_blksz / chead->ch_nchkperblk)
- sizeof (chunk_t);
}
/* Zero misc variables */
chunk_grp = NULL;
dont_unchunk_group = 0;
chunk_initialized = 1;
}
/*
* chunk_new_block() - Allocate new block, initialize it and it's chunks.
*/
static int
chunk_new_block (chunk_head_t *chead)
{
register int idx;
register char *c;
chunk_block_t *blk;
chunk_t *cnk;
/* Map block header mem */
blk = (chunk_block_t *)
mmap(NULL, sizeof(chunk_block_t),
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (blk == MAP_FAILED)
return -1;
memset ((void *)blk, 0, sizeof(*blk));
/* Allocate chunk block */
blk->cb_blk = (void *)
mmap(NULL, chead->ch_blksz,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (blk->cb_blk == MAP_FAILED) {
munmap (blk, chead->ch_blksz);
return -1;
}
memset (blk->cb_blk, 0, chead->ch_blksz);
/* Initialize chunk header */
blk->cb_head = chead;
INSQ (blk, chead->ch_blks);
chead->ch_nblks++;
/* Initialize chunks */
c = ((char *)blk->cb_blk);
for (idx = 0; idx < chead->ch_nchkperblk; idx++) {
cnk = (chunk_t *)c;
cnk->c_blk = blk;
INSQ (cnk, chead->ch_free);
chead->ch_nfree++;
c += (chead->ch_size + sizeof (chunk_t));
}
return 0;
}
/*
* chunk_release_block() - Unqueue a block, it's chunks and free mem
*/
static void
chunk_release_block (chunk_block_t *cblk)
{
int idx;
char *c;
chunk_t *cnk;
chunk_head_t *chead;
chead = cblk->cb_head;
/*
* Dequeue block
*/
DELQ (cblk, chead->ch_blks, chunk_block_t *);
chead->ch_nblks--;
/*
* Dequeue all chunks in the block
*/
c = (char *)cblk->cb_blk;
for (idx = 0; idx < chead->ch_nchkperblk; idx++) {
cnk = (chunk_t *)c;
DELQ (cnk, chead->ch_free, chunk_t *);
chead->ch_nfree--;
c += (chead->ch_size + sizeof (chunk_t));
}
/*
* Free block
*/
munmap ((void *)cblk->cb_blk, chead->ch_blksz);
munmap ((void *)cblk, sizeof(*cblk));
}
/*
* chunk_alloc() - Map new chunk of memory
*/
static void *
chunk_alloc (size_t len)
{
register int idx;
chunk_head_t *chead;
chunk_t *cnk;
if (!len)
return (void *)NULL;
/* Find sufficient sized block head */
for (idx = 0; idx < CHUNK_HEADS; idx++)
if (chunk_heads[idx].ch_size >= len)
break;
/* Too large chunk? */
if (idx >= CHUNK_HEADS) {
errno = ENOMEM;
return (void *)NULL;
}
chead = &chunk_heads[idx];
/* Get new block if necessary */
if (!chead->ch_nfree)
if (chunk_new_block (chead))
return (void *)NULL;
/* Move a free chunk to the in-use list */
cnk = chead->ch_free;
DELQ (cnk, chead->ch_free, chunk_t *);
chead->ch_nfree--;
INSQ (cnk, chead->ch_cnks);
/* Add reference to the corresponding block */
cnk->c_blk->cb_ref++;
#ifdef CHUNK_DIAG
/* Clear diag info */
bzero ((void *)&cnk->c_diag, sizeof (cnk->c_diag));
#endif /* CHUNK_DIAG */
/* Return pointer to first byte after the chunk header */
return (void *) (cnk + 1);
}
/*
* chunk() - Map new chunk of memory in group
*/
void *
#ifdef CHUNK_DIAG
_chunk (size_t len, const char *name, const char *file, int line)
#else
chunk (size_t len, const char *name)
#endif
{
int newgrp = 0;
void *ptr = NULL;
chunk_t *cnk;
chunk_group_t *tmp;
chunk_group_t *grp = NULL;
chunk_grpent_t *ent = NULL;
/* Make sure chunk_heads are initialized */
if (!chunk_initialized)
chunk_initialize();
if (!len)
return (void *)NULL;
/* Get actual chunk
*/
ptr = chunk_alloc (len);
if (!ptr)
goto error;
cnk = (chunk_t *) (((char *)ptr) - sizeof (chunk_t));
#ifdef CHUNK_DIAG
/* Store who reuested us
*/
cnk->c_diag.cd_file = file;
cnk->c_diag.cd_line = line;
#endif /* CHUNK_DIAG */
/* No name given. Get an ungrouped chunk
*/
if (!name)
return ptr;
/* Try to find already existing entry
*/
if (chunk_grp) {
tmp = chunk_grp;
do {
if (!strcmp (tmp->cg_name, name)) {
grp = tmp;
break;
}
tmp = NEXTQ(chunk_group_t *, tmp);
} while (tmp != chunk_grp);
}
/* New group.
*/
if ( !grp ) {
grp = (chunk_group_t *) chunk_alloc (sizeof (chunk_group_t));
if (!grp)
goto error;
bzero (grp, sizeof (chunk_group_t));
grp->cg_name = (char *) chunk_alloc (strlen (name) + 1);
if (!grp->cg_name)
goto error;
bcopy (name, grp->cg_name, strlen(name)+1);
newgrp = 1;
}
/* Get new entry.
*/
ent = (chunk_grpent_t *) chunk_alloc (sizeof (chunk_grpent_t));
if (!ent)
goto error;
bzero (ent, sizeof (chunk_grpent_t));
/* Now put everything together
*/
cnk->c_grpent = ent;
ent->ce_cnk = cnk;
ent->ce_grp = grp;
INSQ (ent, grp->cg_ent);
if (newgrp)
INSQ (grp, chunk_grp);
return (ptr);
error:
if (grp && newgrp) {
if (grp->cg_name)
unchunk (grp->cg_name);
unchunk (grp);
}
if (ent)
unchunk (ent);
if (ptr)
unchunk (ptr);
return (void *) NULL;
}
/*
* rechunk() - Resize previously allocated chunk.
*/
void *
#ifdef CHUNK_DIAG
_rechunk (void *ptr, size_t len, const char *name, const char *file, int line)
#else
rechunk (void *ptr, size_t len, const char *name)
#endif
{
int idx;
void *new;
chunk_t *cnk;
chunk_t *newcnk;
chunk_head_t *chead;
chunk_head_t *newchead;
/* No previoud chunk, get new
*/
if (!ptr) {
#ifdef CHUNK_DIAG
return _chunk (len, name, file, line);
#else
return chunk (len, name);
#endif
}
/* Zero length, free chunk
*/
if (len == 0) {
unchunk (ptr);
return (void *) NULL;
}
/* Rewind pointer to beginning of chunk header
*/
cnk = (chunk_t *) (((char *)ptr) - sizeof (chunk_t));
chead = cnk->c_blk->cb_head;
/* Find sufficient sized block head
*/
for (idx = 0; idx < CHUNK_HEADS; idx++)
if (chunk_heads[idx].ch_size >= len)
break;
/* Too large chunk? */
if (idx >= CHUNK_HEADS) {
errno = ENOMEM;
return (void *)NULL;
}
/* Check if chunk size remains unchanged
*/
if (chunk_heads[idx].ch_size == chead->ch_size)
return (ptr);
/* Get new chunk
*/
#ifdef CHUNK_DIAG
new = _chunk (len, name, file, line);
#else
new = chunk (len, name);
#endif
if (!new)
return (void *) NULL;
newcnk = (chunk_t *) (((char *)new) - sizeof (chunk_t));
newchead = newcnk->c_blk->cb_head;
/* Copy contents to new chunk
*/
bcopy (ptr, new, MIN(newchead->ch_size, chead->ch_size));
/* Free old chunk
*/
unchunk (ptr);
return (new);
}
/*
* unchunk() - Release chunk
*/
void
unchunk (void *ptr)
{
chunk_t *cnk;
chunk_head_t *chead;
chunk_block_t *cblk;
chunk_grpent_t *ent;
chunk_group_t *grp;
if (!chunk_initialized)
return;
/* Rewind pointer to beginning of chunk header
*/
cnk = (chunk_t *) (((char *)ptr) - sizeof (chunk_t));
cblk = cnk->c_blk;
chead = cblk->cb_head;
/* Move chunk back to free list
*/
DELQ (cnk, chead->ch_cnks, chunk_t *);
INSQ (cnk, chead->ch_free);
chead->ch_nfree++;
/* If chunk is grouped, remove from group.
*/
ent = cnk->c_grpent;
if (ent) {
grp = ent->ce_grp;
DELQ (ent, grp->cg_ent, chunk_grpent_t *);
unchunk (ent);
cnk->c_grpent = NULL;
/* Group empty? */
if (!dont_unchunk_group && !grp->cg_ent) {
DELQ (grp, chunk_grp, chunk_group_t *);
unchunk(grp->cg_name);
unchunk(grp);
}
}
/* Check block refs is nil, if so free it
*/
cblk->cb_ref--;
if (cblk->cb_ref == 0)
chunk_release_block (cblk);
}
/*
* unchunk_group() - Release all group chunks.
*/
void
unchunk_group (const char *name)
{
chunk_group_t *tmp;
chunk_group_t *grp = NULL;
chunk_t *cnk;
if (!chunk_initialized)
return;
/* Try to find already existing entry
*/
if (chunk_grp) {
tmp = chunk_grp;
do {
if (!strcmp (tmp->cg_name, name)) {
grp = tmp;
break;
}
tmp = NEXTQ(chunk_group_t *, tmp);
} while (tmp != chunk_grp);
}
if (!grp)
return;
/* Walk through all chunks in group an free them
*/
dont_unchunk_group = 1;
while (grp->cg_ent) {
cnk = grp->cg_ent->ce_cnk;
unchunk ((chunk_t *)(((char *)cnk) + sizeof (chunk_t)));
}
dont_unchunk_group = 0;
/* Remove group from list and free it
*/
DELQ (grp, chunk_grp, chunk_group_t *);
unchunk (grp->cg_name);
unchunk (grp);
}
/*
* chunkdup() - Copy block of data to a new chunk of memory in group
*/
void *
#ifdef CHUNK_DIAG
_chunkdup (const void *ptr, size_t len, const char *name, const char *file, int line)
#else
chunkdup (const void *ptr, size_t len, const char *name)
#endif
{
void *new;
/* No input data or no length
*/
if (!ptr || len <= 0)
return (void *)NULL;
/* Get new chunk
*/
#ifdef CHUNK_DIAG
new = _chunk (len, name, file, line);
#else
new = chunk (len, name);
#endif
if (!new)
return (void *)NULL;
/* Copy data to new chunk
*/
memcpy(new, ptr, len);
return (new);
}
/*
* chunksize() - Return size of memory chunk.
*/
size_t
chunksize (void *ptr)
{
chunk_t *cnk;
chunk_head_t *chead;
chunk_block_t *cblk;
if (!chunk_initialized)
return -1;
/* Rewind pointer to beginning of chunk header
*/
cnk = (chunk_t *) (((char *)ptr) - sizeof (chunk_t));
cblk = cnk->c_blk;
chead = cblk->cb_head;
return chead->ch_size;
}
/*
* chunk_strncat() - Concatenate 'n' characters to a chunk allocated string. If
* 'n' is zero, do the whole src string.
*
*/
char *
#ifdef CHUNK_DIAG
_chunk_strncat (const char *dst, const char *src, size_t n, const char *name,
const char *file, int line)
#else
chunk_strncat (const char *dst, const char *src, size_t n, const char *name)
#endif
{
size_t len;
char *new;
void *ptr = (void *)dst;
if (n == 0) /* zero length means cat whole string */
n = strlen(src);
len = (dst ? strlen(dst) : 0) + n + 1;
#ifdef CHUNK_DIAG
ptr = _rechunk(ptr, len, name, file, line);
#else
ptr = rechunk (ptr, len, name);
#endif
if (ptr == NULL)
return NULL;
new = (char *)ptr;
new += strlen(new);
while (n-- > 0 && *src)
*new++ = *src++;
*new = '\0';
return (char *)ptr;
}
/*
* chunk_sprintf() - Format string into new chunk.
*/
char *
#ifdef CHUNK_DIAG
_chunk_sprintf (const char *name, const char *file,
int line, const char *fmt, ...)
#else
chunk_sprintf (const char *name, char *fmt, ...)
#endif
{
size_t len;
char *str;
va_list args;
/* Calculate formatted string length */
va_start(args, fmt);
len = vsnprintf(NULL, 0, fmt, args) + 1;
va_end (args);
/* get chunk */
#ifdef CHUNK_DIAG
str = _chunk (len, name, file, line);
#else
str = chunk (len, name);
#endif
if (str == NULL)
return NULL;
/* Format string */
va_start(args, fmt);
len = vsnprintf(str, len, fmt, args);
va_end (args);
return str;
}
#ifdef CHUNK_DIAG
/*
* chunk_check() - Report all non-freed chunk for given group (if any)
*/
void
chunk_check(FILE *fout, const char *name)
{
int idx;
chunk_t *cnk;
chunk_group_t *tmp;
chunk_group_t *grp = NULL;
chunk_grpent_t *ent;
if (!chunk_initialized)
return;
/* No name given, walk through everything
*/
if (name == (const char *)NULL) {
for (idx = 0; idx < CHUNK_HEADS; idx++) {
chunk_head_t *chead = &chunk_heads[idx];
cnk = chead->ch_cnks;
if (cnk == (chunk_t *)NULL)
continue;
do {
/* If no file name it's an internal chunk */
if (cnk->c_diag.cd_file)
clicon_debug(0,
"%s:%d,\t%zu bytes (%p), group \"%s\"\n",
cnk->c_diag.cd_file,
cnk->c_diag.cd_line,
cnk->c_blk->cb_head->ch_size,
(cnk +1),
cnk->c_grpent ?
cnk->c_grpent->ce_grp->cg_name :
"NULL");
cnk = NEXTQ(chunk_t *, cnk);
} while (cnk != chead->ch_cnks);
}
}
/* Walk through group
*/
else {
/* Try to find already existing entry
*/
if (chunk_grp) {
tmp = chunk_grp;
do {
if (!strcmp (tmp->cg_name, name)) {
grp = tmp;
break;
}
tmp = NEXTQ(chunk_group_t *, tmp);
} while (tmp != chunk_grp);
}
if (!grp)
return;
ent = grp->cg_ent;
do {
cnk = ent->ce_cnk;
fprintf(fout ? fout : stdout,
"%s:%d,\t%zu bytes (%p), group \"%s\"\n",
cnk->c_diag.cd_file,
cnk->c_diag.cd_line,
cnk->c_blk->cb_head->ch_size,
(cnk +1),
cnk->c_grpent ?
cnk->c_grpent->ce_grp->cg_name :
"NULL");
ent = NEXTQ(chunk_grpent_t *, ent);
} while (ent != grp->cg_ent);
}
}
#else /* CHUNK_DIAG */
void
chunk_check(FILE *fout, const char *name)
{
}
#endif /* CHUNK_DIAG */

View file

@ -57,7 +57,6 @@
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_err.h"
/*
@ -217,7 +216,7 @@ clicon_err_save(void)
{
struct err_state *es;
if ((es = chunk(sizeof(*es), NULL)) == NULL)
if ((es = malloc(sizeof(*es))) == NULL)
return NULL;
es->es_errno = clicon_errno;
es->es_suberrno = clicon_suberrno;
@ -232,10 +231,11 @@ clicon_err_restore(void* handle)
{
struct err_state *es;
es = (struct err_state *)handle;
clicon_errno = es->es_errno;
clicon_suberrno = es->es_suberrno;
strncpy(clicon_err_reason, es->es_reason, ERR_STRLEN-1);
unchunk(es);
if ((es = (struct err_state *)handle) != NULL){
clicon_errno = es->es_errno;
clicon_suberrno = es->es_suberrno;
strncpy(clicon_err_reason, es->es_reason, ERR_STRLEN-1);
free(es);
}
return 0;
}

View file

@ -58,7 +58,6 @@
/* clicon */
#include "clixon_err.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_string.h"
#include "clixon_file.h"
@ -66,7 +65,8 @@
* qsort function
*/
static int
clicon_file_dirent_sort(const void* arg1, const void* arg2)
clicon_file_dirent_sort(const void* arg1,
const void* arg2)
{
struct dirent *d1 = (struct dirent *)arg1;
struct dirent *d2 = (struct dirent *)arg2;
@ -81,10 +81,10 @@ clicon_file_dirent_sort(const void* arg1, const void* arg2)
/*! Return sorted matching files from a directory
* @param[in] dir Directory path
* @param[out] ent Entries pointer, will be filled in with dir entries
* @param[out] ent Entries pointer, will be filled in with dir entries. Free
* after use
* @param[in] regexp Regexp filename matching
* @param[in] type File type matching, see stat(2)
* @param[in] label Clicon Chunk label for memory handling, unchunk after use
*
* @retval n Number of matching files in directory
* @retval -1 Error
@ -92,34 +92,34 @@ clicon_file_dirent_sort(const void* arg1, const void* arg2)
* @code
* char *dir = "/root/fs";
* struct dirent *dp;
* if ((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__)) < 0)
* if ((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG)) < 0)
* return -1;
* for (i = 0; i < ndp; i++)
* do something with dp[i].d_name;
* unchunk_group(__FUNCTION__);
* free(dp);
* @endcode
*/
int
clicon_file_dirent(const char *dir,
struct dirent **ent,
const char *regexp,
mode_t type,
const char *label)
mode_t type)
{
DIR *dirp;
int retval = -1;
int res;
int nent;
char *filename;
regex_t re;
char errbuf[128];
struct stat st;
struct dirent dent;
int retval = -1;
DIR *dirp;
int res;
int nent;
regex_t re;
char errbuf[128];
char filename[MAXPATHLEN];
struct stat st;
struct dirent dent;
struct dirent *dresp;
struct dirent *tmp;
struct dirent *new = NULL;
struct dirent *dvecp = NULL;
*ent = NULL;
nent = 0;
@ -137,7 +137,9 @@ clicon_file_dirent(const char *dir,
goto quit;
}
for (res = readdir_r (dirp, &dent, &dresp); dresp; res = readdir_r (dirp, &dent, &dresp)) {
for (res = readdir_r (dirp, &dent, &dresp);
dresp;
res = readdir_r (dirp, &dent, &dresp)) {
if (res != 0) {
clicon_err(OE_UNIX, 0, "readdir: %s", strerror(errno));
goto quit;
@ -150,12 +152,8 @@ clicon_file_dirent(const char *dir,
}
/* File type matching */
if (type) {
if ((filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dent.d_name)) == NULL) {
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
goto quit;
}
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dent.d_name);
res = lstat(filename, &st);
unchunk (filename);
if (res != 0) {
clicon_err(OE_UNIX, 0, "lstat: %s", strerror(errno));
goto quit;
@ -164,8 +162,8 @@ clicon_file_dirent(const char *dir,
continue;
}
if ((tmp = rechunk(new, (nent+1)*sizeof(*dvecp), label)) == NULL) {
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
if ((tmp = realloc(new, (nent+1)*sizeof(*dvecp))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
}
new = tmp;
@ -183,30 +181,9 @@ quit:
closedir(dirp);
if (regexp)
regfree(&re);
unchunk_group(__FUNCTION__);
return retval;
}
/*
* Use mkstep() to create an empty temporary file, accessible only by this user.
* A chunk:ed file name is returned so that caller can overwrite file safely.
*/
char *
clicon_tmpfile(const char *label)
{
int fd;
char file[] = "/tmp/.tmpXXXXXX";
if ((fd = mkstemp(file)) < 0){
clicon_err(OE_UNIX, errno, "mkstemp");
return NULL;
}
close(fd);
return (char *)chunkdup(file, strlen(file)+1, label);
}
/*! Make a copy of file src
* @retval 0 OK
* @retval -1 Error

View file

@ -61,7 +61,6 @@
#include "clixon_queue.h"
#include "clixon_hash.h"
#include "clixon_handle.h"
#include "clixon_chunk.h"
#include "clixon_log.h"
#include "clixon_yang.h"
#include "clixon_options.h"
@ -198,7 +197,6 @@ clicon_option_default(clicon_hash_t *copt)
}
retval = 0;
catch:
unchunk_group(__FUNCTION__);
return retval;
}
@ -233,10 +231,6 @@ clicon_option_sanity(clicon_hash_t *copt)
clicon_err(OE_UNIX, 0, "CLICON_YANG_DIR not defined in config file");
goto done;
}
if (!hash_lookup(copt, "CLICON_ARCHIVE_DIR")){
clicon_err(OE_UNIX, 0, "CLICON_ARCHIVE_DIR not defined in config file");
goto done;
}
if (!hash_lookup(copt, "CLICON_XMLDB_DIR")){
clicon_err(OE_UNIX, 0, "CLICON_XMLDB_DIR not defined in config file");
goto done;
@ -451,12 +445,6 @@ clicon_restconf_dir(clicon_handle h)
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
}
char *
clicon_archive_dir(clicon_handle h)
{
return clicon_option_str(h, "CLICON_ARCHIVE_DIR");
}
char *
clicon_xmldb_plugin(clicon_handle h)
{

View file

@ -60,7 +60,6 @@
#include "clixon_sig.h"
#include "clixon_string.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_proc.h"
/*

View file

@ -66,7 +66,6 @@
#include "clixon_err.h"
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_sig.h"
#include "clixon_xml.h"
#include "clixon_xsl.h"
@ -532,11 +531,11 @@ send_msg_reply(int s,
uint16_t datalen)
{
int retval = -1;
struct clicon_msg *reply;
struct clicon_msg *reply = NULL;
uint16_t len;
len = sizeof(*reply) + datalen;
if ((reply = (struct clicon_msg *)chunk(len, __FUNCTION__)) == NULL)
if ((reply = (struct clicon_msg *)malloc(len)) == NULL)
goto done;
memset(reply, 0, len);
reply->op_len = htons(len);
@ -546,7 +545,8 @@ send_msg_reply(int s,
goto done;
retval = 0;
done:
unchunk_group(__FUNCTION__);
if (reply)
free(reply);
return retval;
}

View file

@ -56,7 +56,6 @@
/* clicon */
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_log.h"
#include "clixon_hash.h"
#include "clixon_handle.h"

View file

@ -49,7 +49,6 @@
/* clicon */
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_string.h"
#include "clixon_err.h"

View file

@ -51,7 +51,6 @@
#include "clixon_err.h"
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_xml.h"
#include "clixon_xml_parse.h"

View file

@ -46,7 +46,6 @@
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <curl/curl.h>
#include <libgen.h>
/* cligen */
@ -128,14 +127,36 @@ xmldb_get(clicon_handle h, char *db, char *xpath,
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_get_fn &&
_xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen) < 0)
if (_xa_api->xa_get_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen);
done:
return retval;
}
/*! Modify database provided an xml tree and an operation
*
* @param[in] h CLICON handle
* @param[in] db running or candidate
* @param[in] xt xml-tree. Top-level symbol is dummy
* @param[in] op OP_MERGE: just add it.
* OP_REPLACE: first delete whole database
* OP_NONE: operation attribute in xml determines operation
* @param[in] api_path According to restconf (Sec 3.5.1.1 in [restconf-draft 13])
* @retval 0 OK
* @retval -1 Error
* The xml may contain the "operation" attribute which defines the operation.
* @code
* cxobj *xt;
* if (clicon_xml_parse_str("<a>17</a>", &xt) < 0)
* err;
* if (xmldb_put(h, "running", OP_MERGE, NULL, xt) < 0)
* err;
* @endcode
* @see xmldb_put_xkey for single key
*/
int
xmldb_put(clicon_handle h, char *db, enum operation_type op,
char *api_path, cxobj *xt)
@ -146,16 +167,24 @@ xmldb_put(clicon_handle h, char *db, enum operation_type op,
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_put_fn &&
_xa_api->xa_put_fn(h, db, op, api_path, xt) < 0)
if (_xa_api->xa_put_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_put_fn(h, db, op, api_path, xt);
done:
return retval;
}
/*! Raw dump of database, in internal format (depends on datastore)
* @param[in] f File
* @param[in] dbfile File-name of database. This is a local file
* @param[in] pattern Key regexp, eg "^.*$"
*/
int
xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
xmldb_dump(FILE *f,
char *dbfilename,
char *pattern)
{
int retval = -1;
@ -163,14 +192,22 @@ xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_dump_fn &&
_xa_api->xa_dump_fn(f, dbfilename, rxkey) < 0)
if (_xa_api->xa_dump_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_dump_fn(f, dbfilename, pattern);
done:
return retval;
}
/*! Copy database from db1 to db2
* @param[in] h Clicon handle
* @param[in] from Source database copy
* @param[in] to Destination database
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_copy(clicon_handle h, char *from, char *to)
{
@ -180,14 +217,22 @@ xmldb_copy(clicon_handle h, char *from, char *to)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_copy_fn &&
_xa_api->xa_copy_fn(h, from, to) < 0)
if (_xa_api->xa_copy_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_copy_fn(h, from, to);
done:
return retval;
}
/*! Lock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_lock(clicon_handle h, char *db, int pid)
{
@ -197,14 +242,23 @@ xmldb_lock(clicon_handle h, char *db, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_lock_fn &&
_xa_api->xa_lock_fn(h, db, pid) < 0)
if (_xa_api->xa_lock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_lock_fn(h, db, pid);
done:
return retval;
}
/*! Unlock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
* Assume all sanity checks have been made
*/
int
xmldb_unlock(clicon_handle h, char *db, int pid)
{
@ -214,14 +268,21 @@ xmldb_unlock(clicon_handle h, char *db, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_fn &&
_xa_api->xa_unlock_fn(h, db, pid) < 0)
if (_xa_api->xa_unlock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_unlock_fn(h, db, pid);
done:
return retval;
}
/*! Unlock all databases locked by pid (eg process dies)
* @param[in] h Clicon handle
* @param[in] pid Process / Session id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_unlock_all(clicon_handle h, int pid)
{
@ -231,14 +292,22 @@ xmldb_unlock_all(clicon_handle h, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_all_fn &&
_xa_api->xa_unlock_all_fn(h, pid) < 0)
if (_xa_api->xa_unlock_all_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval =_xa_api->xa_unlock_all_fn(h, pid);
done:
return retval;
}
/*! Check if database is locked
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 Not locked
* @retval >0 Id of locker
*/
int
xmldb_islocked(clicon_handle h, char *db)
{
@ -248,14 +317,22 @@ xmldb_islocked(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_islocked_fn &&
_xa_api->xa_islocked_fn(h, db) < 0)
if (_xa_api->xa_islocked_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval =_xa_api->xa_islocked_fn(h, db);
done:
return retval;
}
/*! Check if db exists
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 No it does not exist
* @retval 1 Yes it exists
*/
int
xmldb_exists(clicon_handle h, char *db)
{
@ -265,14 +342,21 @@ xmldb_exists(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_exists_fn &&
_xa_api->xa_exists_fn(h, db) < 0)
if (_xa_api->xa_exists_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_exists_fn(h, db);
done:
return retval;
}
/*! Delete database. Remove file
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_delete(clicon_handle h, char *db)
{
@ -282,14 +366,21 @@ xmldb_delete(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_delete_fn &&
_xa_api->xa_delete_fn(h, db) < 0)
if (_xa_api->xa_delete_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_delete_fn(h, db);
done:
return retval;
}
/*! Initialize database
* @param[in] h Clicon handle
* @param[in] db Database
* @retval 0 OK
* @retval -1 Error
*/
int
xmldb_init(clicon_handle h, char *db)
{
@ -299,10 +390,11 @@ xmldb_init(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_init_fn &&
_xa_api->xa_init_fn(h, db) < 0)
if (_xa_api->xa_init_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_init_fn(h, db);
done:
return retval;
}

View file

@ -76,7 +76,6 @@
#include "clixon_string.h"
#include "clixon_queue.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"
@ -125,8 +124,9 @@ xml2txt(FILE *f, cxobj *x, int level)
{
cxobj *xe = NULL;
int children=0;
char *term;
char *term = NULL;
int retval = -1;
int encr=0;
#ifdef SPECIAL_TREATMENT_OF_NAME
cxobj *xname;
#endif
@ -138,15 +138,17 @@ xml2txt(FILE *f, cxobj *x, int level)
if (xml_type(x) == CX_BODY){
/* Kludge for escaping encrypted passwords */
if (strcmp(xml_name(xml_parent(x)), "encrypted-password")==0)
term = chunk_sprintf(__FUNCTION__, "\"%s\"", xml_value(x));
else
term = xml_value(x);
encr++;
term = xml_value(x);
}
else{
fprintf(f, "%*s", 4*level, "");
term = xml_name(x);
}
fprintf(f, "%s;\n", term);
if (encr)
fprintf(f, "\"%s\";\n", term);
else
fprintf(f, "%s;\n", term);
retval = 0;
goto done;
}

View file

@ -66,7 +66,6 @@
#include "clixon_file.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_options.h"
#include "clixon_yang_type.h"
#include "clixon_yang_parse.h"
@ -1382,20 +1381,21 @@ yang_parse_file(clicon_handle h,
* @retval 1 Match founbd, Most recent entry returned in fbuf
* @retval 0 No matching entry found
* @retval -1 Error
*/static int
*/
static int
yang_parse_find_match(clicon_handle h,
const char *yang_dir,
const char *module,
cbuf *fbuf)
{
int retval = -1;
struct dirent *dp;
struct dirent *dp = NULL;
int ndp;
cbuf *regex = NULL;
char *regexstr;
if ((regex = cbuf_new()) == NULL){
clicon_err(OE_YANG, errno, "%s: cbuf_new", __FUNCTION__);
clicon_err(OE_YANG, errno, "cbuf_new");
goto done;
}
cprintf(regex, "^%s.*(.yang)$", module);
@ -1403,8 +1403,7 @@ yang_parse_find_match(clicon_handle h,
if ((ndp = clicon_file_dirent(yang_dir,
&dp,
regexstr,
S_IFREG,
__FUNCTION__)) < 0)
S_IFREG)) < 0)
goto done;
/* Entries are sorted, last entry should be most recent date */
if (ndp != 0){
@ -1416,7 +1415,8 @@ yang_parse_find_match(clicon_handle h,
done:
if (regex)
cbuf_free(regex);
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}

View file

@ -63,7 +63,6 @@
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_options.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"