Created xmldb plugin api
This commit is contained in:
parent
4169bd8d30
commit
f6b3e95100
39 changed files with 492 additions and 504 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@
|
|||
#include "clixon_sig.h"
|
||||
#include "clixon_string.h"
|
||||
#include "clixon_queue.h"
|
||||
#include "clixon_chunk.h"
|
||||
#include "clixon_proc.h"
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@
|
|||
|
||||
/* clicon */
|
||||
#include "clixon_queue.h"
|
||||
#include "clixon_chunk.h"
|
||||
#include "clixon_string.h"
|
||||
#include "clixon_err.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue