Added restconf handle specialization to implement restconf parameters
This commit is contained in:
parent
1597bd303c
commit
73bbcded87
22 changed files with 351 additions and 162 deletions
|
|
@ -2,7 +2,8 @@
|
||||||
*
|
*
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
|
||||||
This file is part of CLIXON.
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
*
|
*
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
|
||||||
This file is part of CLIXON.
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ APPOBJ = $(APPSRC:.c=.o)
|
||||||
# (eg restconf_method_notallowed) that uses symbols in restconf_api that
|
# (eg restconf_method_notallowed) that uses symbols in restconf_api that
|
||||||
# are not in the lib.
|
# are not in the lib.
|
||||||
LIBSRC = restconf_lib.c
|
LIBSRC = restconf_lib.c
|
||||||
|
LIBSRC += restconf_handle.c
|
||||||
|
|
||||||
LIBOBJ = $(LIBSRC:.c=.o)
|
LIBOBJ = $(LIBSRC:.c=.o)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,8 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||||
int restconf_terminate(clicon_handle h);
|
int restconf_terminate(clicon_handle h);
|
||||||
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
|
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
|
||||||
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
|
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
|
||||||
char *clixon_restconf_param_get(clicon_handle h, char *param);
|
/* also in restconf_handle.h */
|
||||||
int clixon_restconf_param_set(clicon_handle h, char *param, char *val);
|
char *restconf_param_get(clicon_handle h, char *param);
|
||||||
|
int restconf_param_set(clicon_handle h, char *param, char *val);
|
||||||
|
|
||||||
#endif /* _CLIXON_RESTCONF_H_ */
|
#endif /* _CLIXON_RESTCONF_H_ */
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ restconf_badrequest(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "The requested URL %s or data is in some way badly formed.\n", path);
|
cprintf(cb, "The requested URL %s or data is in some way badly formed.\n", path);
|
||||||
|
|
@ -137,7 +137,7 @@ restconf_unauthorized(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "<error-tag>access-denied</error-tag>\n");
|
cprintf(cb, "<error-tag>access-denied</error-tag>\n");
|
||||||
|
|
@ -175,7 +175,7 @@ restconf_forbidden(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "The requested URL %s was forbidden.\n", path);
|
cprintf(cb, "The requested URL %s was forbidden.\n", path);
|
||||||
|
|
@ -213,7 +213,7 @@ restconf_notfound(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "The requested URL %s was not found on this server.\n", path);
|
cprintf(cb, "The requested URL %s was not found on this server.\n", path);
|
||||||
|
|
@ -270,7 +270,7 @@ restconf_notacceptable(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "The target resource does not have a current representation that would be acceptable to the user agent.\n", path);
|
cprintf(cb, "The target resource does not have a current representation that would be acceptable to the user agent.\n", path);
|
||||||
|
|
@ -338,7 +338,7 @@ restconf_internal_server_error(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
|
path = restconf_param_get("REQUEST_URI", r->envp);
|
||||||
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "Internal server error when accessing %s</h1>\n", path);
|
cprintf(cb, "Internal server error when accessing %s</h1>\n", path);
|
||||||
|
|
|
||||||
174
apps/restconf/restconf_handle.c
Normal file
174
apps/restconf/restconf_handle.c
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
|
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 <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clicon */
|
||||||
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
|
#include "restconf_handle.h"
|
||||||
|
|
||||||
|
/* header part is copied from struct clicon_handle in lib/src/clixon_handle.c */
|
||||||
|
|
||||||
|
#define CLICON_MAGIC 0x99aafabe
|
||||||
|
|
||||||
|
#define handle(h) (assert(clicon_handle_check(h)==0),(struct restconf_handle *)(h))
|
||||||
|
|
||||||
|
/* Clicon_handle for backends.
|
||||||
|
* First part of this is header, same for clicon_handle and cli_handle.
|
||||||
|
* Access functions for common fields are found in clicon lib: clicon_options.[ch]
|
||||||
|
* 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 restconf_handle {
|
||||||
|
int rh_magic; /* magic (HDR)*/
|
||||||
|
clicon_hash_t *rh_copt; /* clicon option list (HDR) */
|
||||||
|
clicon_hash_t *rh_data; /* internal clicon data (HDR) */
|
||||||
|
clicon_hash_t *rh_db_elmnt; /* xml datastore element cache data */
|
||||||
|
event_stream_t *rh_stream; /* notification streams, see clixon_stream.[ch] */
|
||||||
|
|
||||||
|
/* ------ end of common handle ------ */
|
||||||
|
clicon_hash_t *rh_params; /* restconf parameters, including http headers */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Creates and returns a clicon config handle for other CLICON API calls
|
||||||
|
*/
|
||||||
|
clicon_handle
|
||||||
|
restconf_handle_init(void)
|
||||||
|
{
|
||||||
|
return clicon_handle_init0(sizeof(struct restconf_handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Deallocates a backend handle, including all client structs
|
||||||
|
* @note: handle 'h' cannot be used in calls after this
|
||||||
|
* @see backend_client_rm
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
restconf_handle_exit(clicon_handle h)
|
||||||
|
{
|
||||||
|
clicon_handle_exit(h); /* frees h and options (and streams) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Get restconf http parameter
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] name Data name
|
||||||
|
* @retval val Data value as string
|
||||||
|
* Currently using clixon runtime data but there is risk for colliding names
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
restconf_param_get(clicon_handle h,
|
||||||
|
char *param)
|
||||||
|
{
|
||||||
|
struct restconf_handle *rh = handle(h);
|
||||||
|
|
||||||
|
if (rh->rh_params == NULL)
|
||||||
|
return NULL;
|
||||||
|
return (char*)clicon_hash_value(rh->rh_params, param, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set restconf http parameter
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] name Data name
|
||||||
|
* @param[in] val Data value as null-terminated string
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
* Currently using clixon runtime data but there is risk for colliding names
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
restconf_param_set(clicon_handle h,
|
||||||
|
char *param,
|
||||||
|
char *val)
|
||||||
|
{
|
||||||
|
struct restconf_handle *rh = handle(h);
|
||||||
|
|
||||||
|
clicon_debug(1, "%s=%s", param, val);
|
||||||
|
if (rh->rh_params == NULL)
|
||||||
|
if ((rh->rh_params = clicon_hash_init()) == NULL)
|
||||||
|
return -1;
|
||||||
|
return clicon_hash_add(rh->rh_params, param, val, strlen(val)+1)==NULL?-1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Delete all restconf http parameter
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] name Data name
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
* Currently using clixon runtime data but there is risk for colliding names
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
restconf_param_del_all(clicon_handle h)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
struct restconf_handle *rh = handle(h);
|
||||||
|
|
||||||
|
if (rh->rh_params != NULL){
|
||||||
|
if (clicon_hash_free(rh->rh_params) < 0)
|
||||||
|
goto done;
|
||||||
|
rh->rh_params = NULL;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
51
apps/restconf/restconf_handle.h
Normal file
51
apps/restconf/restconf_handle.h
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
|
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 *****
|
||||||
|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RESTCONF_HANDLE_H_
|
||||||
|
#define _RESCTONF_HANDLE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes
|
||||||
|
*/
|
||||||
|
clicon_handle restconf_handle_init(void);
|
||||||
|
int restconf_handle_exit(clicon_handle h);
|
||||||
|
char *restconf_param_get(clicon_handle h, char *param);
|
||||||
|
int restconf_param_set(clicon_handle h, char *param, char *val);
|
||||||
|
int restconf_param_del_all(clicon_handle h);
|
||||||
|
|
||||||
|
#endif /* _RESTCONF_HANDLE_H_ */
|
||||||
|
|
@ -60,6 +60,7 @@
|
||||||
#include <clixon/clixon.h>
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
|
||||||
/* See RFC 8040 Section 7: Mapping from NETCONF<error-tag> to Status Code
|
/* See RFC 8040 Section 7: Mapping from NETCONF<error-tag> to Status Code
|
||||||
|
|
@ -188,10 +189,10 @@ restconf_media_int2str(restconf_media media)
|
||||||
restconf_media
|
restconf_media
|
||||||
restconf_content_type(clicon_handle h)
|
restconf_content_type(clicon_handle h)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str = NULL;
|
||||||
restconf_media m;
|
restconf_media m;
|
||||||
|
|
||||||
if ((str = clixon_restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL)
|
if ((str = restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if ((int)(m = restconf_media_str2int(str)) == -1)
|
if ((int)(m = restconf_media_str2int(str)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -252,7 +253,7 @@ restconf_terminate(clicon_handle h)
|
||||||
if ((x = clicon_conf_xml(h)) != NULL)
|
if ((x = clicon_conf_xml(h)) != NULL)
|
||||||
xml_free(x);
|
xml_free(x);
|
||||||
xpath_optimize_exit();
|
xpath_optimize_exit();
|
||||||
clicon_handle_exit(h);
|
restconf_handle_exit(h);
|
||||||
clicon_log_exit();
|
clicon_log_exit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -412,53 +413,6 @@ restconf_main_extension_cb(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get restconf http parameter
|
|
||||||
* @param[in] h Clicon handle
|
|
||||||
* @param[in] name Data name
|
|
||||||
* @retval val Data value as string
|
|
||||||
* Currently using clixon runtime data but there is risk for colliding names
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
clixon_restconf_param_get(clicon_handle h,
|
|
||||||
char *param)
|
|
||||||
{
|
|
||||||
char *val;
|
|
||||||
if (clicon_data_get(h, param, &val) < 0)
|
|
||||||
return NULL;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Set restconf http parameter
|
|
||||||
* @param[in] h Clicon handle
|
|
||||||
* @param[in] name Data name
|
|
||||||
* @param[in] val Data value as null-terminated string
|
|
||||||
* @retval 0 OK
|
|
||||||
* @retval -1 Error
|
|
||||||
* Currently using clixon runtime data but there is risk for colliding names
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
clixon_restconf_param_set(clicon_handle h,
|
|
||||||
char *param,
|
|
||||||
char *val)
|
|
||||||
{
|
|
||||||
clicon_debug(1, "%s=%s", param, val);
|
|
||||||
return clicon_data_set(h, param, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Delete restconf http parameter
|
|
||||||
* @param[in] h Clicon handle
|
|
||||||
* @param[in] name Data name
|
|
||||||
* @retval 0 OK
|
|
||||||
* @retval -1 Error
|
|
||||||
* Currently using clixon runtime data but there is risk for colliding names
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
clixon_restconf_param_del(clicon_handle h,
|
|
||||||
char *param)
|
|
||||||
{
|
|
||||||
return clicon_data_del(h, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Extract uri-encoded uri-path from fastcgi parameters
|
/*! Extract uri-encoded uri-path from fastcgi parameters
|
||||||
* Use REQUEST_URI parameter and strip ?args
|
* Use REQUEST_URI parameter and strip ?args
|
||||||
* REQUEST_URI have args and is encoded
|
* REQUEST_URI have args and is encoded
|
||||||
|
|
@ -473,7 +427,7 @@ restconf_uripath(clicon_handle h)
|
||||||
char *path;
|
char *path;
|
||||||
char *q;
|
char *q;
|
||||||
|
|
||||||
path = clixon_restconf_param_get(h, "REQUEST_URI");
|
path = restconf_param_get(h, "REQUEST_URI");
|
||||||
if ((q = index(path, '?')) != NULL)
|
if ((q = index(path, '?')) != NULL)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
return path;
|
return path;
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,6 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||||
int restconf_terminate(clicon_handle h);
|
int restconf_terminate(clicon_handle h);
|
||||||
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
|
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
|
||||||
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
|
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
|
||||||
char *clixon_restconf_param_get(clicon_handle h, char *param);
|
|
||||||
int clixon_restconf_param_set(clicon_handle h, char *param, char *val);
|
|
||||||
int clixon_restconf_param_del(clicon_handle h, char *param);
|
|
||||||
char *restconf_uripath(clicon_handle h);
|
char *restconf_uripath(clicon_handle h);
|
||||||
int restconf_drop_privileges(clicon_handle h, char *user);
|
int restconf_drop_privileges(clicon_handle h, char *user);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -75,6 +76,7 @@
|
||||||
/* restconf */
|
/* restconf */
|
||||||
|
|
||||||
#include "restconf_lib.h" /* generic shared with plugins */
|
#include "restconf_lib.h" /* generic shared with plugins */
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h" /* generic not shared with plugins */
|
#include "restconf_api.h" /* generic not shared with plugins */
|
||||||
#include "restconf_root.h"
|
#include "restconf_root.h"
|
||||||
|
|
||||||
|
|
@ -202,6 +204,43 @@ query_iterator(evhtp_header_t *hdr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Translate http header by capitalizing, prepend w HTTP_ and - -> _
|
||||||
|
* Example: Host -> HTTP_HOST
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
convert_fcgi(evhtp_header_t *hdr,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
clicon_handle h = (clicon_handle)arg;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
int i;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* convert key name */
|
||||||
|
cprintf(cb, "HTTP_");
|
||||||
|
for (i=0; i<strlen(hdr->key); i++){
|
||||||
|
c = hdr->key[i] & 0xff;
|
||||||
|
if (islower(c))
|
||||||
|
cprintf(cb, "%c", toupper(c));
|
||||||
|
else if (c == '-')
|
||||||
|
cprintf(cb, "_");
|
||||||
|
else
|
||||||
|
cprintf(cb, "%c", c);
|
||||||
|
}
|
||||||
|
if (restconf_param_set(h, cbuf_get(cb), hdr->val) < 0)
|
||||||
|
goto done;
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Map from evhtp information to "fcgi" type parameters used in clixon code
|
/*! Map from evhtp information to "fcgi" type parameters used in clixon code
|
||||||
*
|
*
|
||||||
* While all these params come via one call in fcgi, the information must be taken from
|
* While all these params come via one call in fcgi, the information must be taken from
|
||||||
|
|
@ -230,7 +269,6 @@ evhtp_params_set(clicon_handle h,
|
||||||
htp_method meth;
|
htp_method meth;
|
||||||
evhtp_uri_t *uri;
|
evhtp_uri_t *uri;
|
||||||
evhtp_path_t *path;
|
evhtp_path_t *path;
|
||||||
evhtp_header_t *hdr;
|
|
||||||
|
|
||||||
if ((uri = req->uri) == NULL){
|
if ((uri = req->uri) == NULL){
|
||||||
clicon_err(OE_DAEMON, EFAULT, "No uri");
|
clicon_err(OE_DAEMON, EFAULT, "No uri");
|
||||||
|
|
@ -251,40 +289,16 @@ evhtp_params_set(clicon_handle h,
|
||||||
clicon_err(OE_CFG, errno, "evhtp_kvs_for_each");
|
clicon_err(OE_CFG, errno, "evhtp_kvs_for_each");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clixon_restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0)
|
if (restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clixon_restconf_param_set(h, "REQUEST_URI", path->full) < 0)
|
if (restconf_param_set(h, "REQUEST_URI", path->full) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clixon_restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */
|
if (restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */
|
||||||
goto done;
|
goto done;
|
||||||
if ((hdr = evhtp_headers_find_header(req->headers_in, "Host")) != NULL){
|
/* Translate all http headers by capitalizing, prepend w HTTP_ and - -> _
|
||||||
if (clixon_restconf_param_set(h, "HTTP_HOST", hdr->val) < 0)
|
* Example: Host -> HTTP_HOST
|
||||||
goto done;
|
*/
|
||||||
}
|
if (evhtp_headers_for_each(req->headers_in, convert_fcgi, h) < 0)
|
||||||
if ((hdr = evhtp_headers_find_header(req->headers_in, "Accept")) != NULL){
|
|
||||||
if (clixon_restconf_param_set(h, "HTTP_ACCEPT", hdr->val) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((hdr = evhtp_headers_find_header(req->headers_in, "Content-Type")) != NULL){
|
|
||||||
if (clixon_restconf_param_set(h, "HTTP_CONTENT_TYPE", hdr->val) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
retval = 0;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
evhtp_params_clear(clicon_handle h)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
char *params[] = {"QUERY_STRING", "REQUEST_METHOD", "REQUEST_URI",
|
|
||||||
"HTTPS", "HTTP_HOST", "HTTP_ACCEPT", "HTTP_CONTENT_TYPE", NULL};
|
|
||||||
char *param;
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
while((param=params[i]) != NULL)
|
|
||||||
if (clixon_restconf_param_del(h, param) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -370,7 +384,7 @@ cx_path_wellknown(evhtp_request_t *req,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Clear (fcgi) paramaters from this request */
|
/* Clear (fcgi) paramaters from this request */
|
||||||
if (evhtp_params_clear(h) < 0)
|
if (restconf_param_del_all(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
done:
|
done:
|
||||||
return; /* void */
|
return; /* void */
|
||||||
|
|
@ -404,7 +418,7 @@ cx_path_restconf(evhtp_request_t *req,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Clear (fcgi) paramaters from this request */
|
/* Clear (fcgi) paramaters from this request */
|
||||||
if (evhtp_params_clear(h) < 0)
|
if (restconf_param_del_all(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
done:
|
done:
|
||||||
return; /* void */
|
return; /* void */
|
||||||
|
|
@ -473,7 +487,7 @@ main(int argc,
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
||||||
/* Create handle */
|
/* Create handle */
|
||||||
if ((h = clicon_handle_init()) == NULL)
|
if ((h = restconf_handle_init()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
_CLICON_HANDLE = h; /* for termination handling */
|
_CLICON_HANDLE = h; /* for termination handling */
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
/* restconf */
|
/* restconf */
|
||||||
#include "restconf_lib.h" /* generic shared with plugins */
|
#include "restconf_lib.h" /* generic shared with plugins */
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h" /* generic not shared with plugins */
|
#include "restconf_api.h" /* generic not shared with plugins */
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_root.h" /* generic not shared with plugins */
|
#include "restconf_root.h" /* generic not shared with plugins */
|
||||||
|
|
@ -107,7 +108,7 @@ fcgi_params_set(clicon_handle h,
|
||||||
for (i = 0; envp[i] != NULL; i++){ /* on the form <param>=<value> */
|
for (i = 0; envp[i] != NULL; i++){ /* on the form <param>=<value> */
|
||||||
if (clixon_strsplit(envp[i], '=', ¶m, &val) < 0)
|
if (clixon_strsplit(envp[i], '=', ¶m, &val) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clixon_restconf_param_set(h, param, val) < 0)
|
if (restconf_param_set(h, param, val) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (param){
|
if (param){
|
||||||
free(param);
|
free(param);
|
||||||
|
|
@ -124,35 +125,6 @@ fcgi_params_set(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Clear all FCGI parameters in an environment
|
|
||||||
* @param[in] h Clixon handle
|
|
||||||
* @param[in] envp Fastcgi request handle parameter array on the format "<param>=<value>"
|
|
||||||
* @see https://nginx.org/en/docs/http/ngx_http_core_module.html#var_https
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
fcgi_params_clear(clicon_handle h,
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
int i;
|
|
||||||
char *param = NULL;
|
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
|
||||||
for (i = 0; envp[i] != NULL; i++){ /* on the form <param>=<value> */
|
|
||||||
if (clixon_strsplit(envp[i], '=', ¶m, NULL) < 0)
|
|
||||||
goto done;
|
|
||||||
if (clixon_restconf_param_del(h, param) < 0)
|
|
||||||
goto done;
|
|
||||||
if (param){
|
|
||||||
free(param);
|
|
||||||
param = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retval = 0;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need global variable to for signal handler XXX */
|
/* Need global variable to for signal handler XXX */
|
||||||
static clicon_handle _CLICON_HANDLE = NULL;
|
static clicon_handle _CLICON_HANDLE = NULL;
|
||||||
|
|
||||||
|
|
@ -246,7 +218,7 @@ main(int argc,
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
||||||
/* Create handle */
|
/* Create handle */
|
||||||
if ((h = clicon_handle_init()) == NULL)
|
if ((h = restconf_handle_init()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
_CLICON_HANDLE = h; /* for termination handling */
|
_CLICON_HANDLE = h; /* for termination handling */
|
||||||
|
|
@ -504,12 +476,12 @@ main(int argc,
|
||||||
*/
|
*/
|
||||||
if (fcgi_params_set(h, req->envp) < 0)
|
if (fcgi_params_set(h, req->envp) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((path = clixon_restconf_param_get(h, "REQUEST_URI")) != NULL){
|
if ((path = restconf_param_get(h, "REQUEST_URI")) != NULL){
|
||||||
clicon_debug(1, "path: %s", path);
|
clicon_debug(1, "path: %s", path);
|
||||||
if (strncmp(path, "/" RESTCONF_API, strlen("/" RESTCONF_API)) == 0){
|
if (strncmp(path, "/" RESTCONF_API, strlen("/" RESTCONF_API)) == 0){
|
||||||
char *query = NULL;
|
char *query = NULL;
|
||||||
cvec *qvec = NULL;
|
cvec *qvec = NULL;
|
||||||
query = clixon_restconf_param_get(h, "QUERY_STRING");
|
query = restconf_param_get(h, "QUERY_STRING");
|
||||||
if (query != NULL && strlen(query))
|
if (query != NULL && strlen(query))
|
||||||
if (str2cvec(query, '&', '=', &qvec) < 0)
|
if (str2cvec(query, '&', '=', &qvec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -532,7 +504,7 @@ main(int argc,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
clicon_debug(1, "NULL URI");
|
clicon_debug(1, "NULL URI");
|
||||||
if (fcgi_params_clear(h, req->envp) < 0)
|
if (restconf_param_del_all(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (finish)
|
if (finish)
|
||||||
FCGX_Finish_r(req);
|
FCGX_Finish_r(req);
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ Mapping netconf error-tag -> status code
|
||||||
#include <clixon/clixon.h>
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_methods.h"
|
#include "restconf_methods.h"
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@
|
||||||
#include <clixon/clixon.h>
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_methods_get.h"
|
#include "restconf_methods_get.h"
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@
|
||||||
#include <clixon/clixon.h>
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_methods_post.h"
|
#include "restconf_methods_post.h"
|
||||||
|
|
@ -81,9 +82,9 @@ http_location_header(clicon_handle h,
|
||||||
char *request_uri;
|
char *request_uri;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
https = clixon_restconf_param_get(h, "HTTPS");
|
https = restconf_param_get(h, "HTTPS");
|
||||||
host = clixon_restconf_param_get(h, "HTTP_HOST");
|
host = restconf_param_get(h, "HTTP_HOST");
|
||||||
request_uri = clixon_restconf_param_get(h, "REQUEST_URI");
|
request_uri = restconf_param_get(h, "REQUEST_URI");
|
||||||
if (xobj != NULL){
|
if (xobj != NULL){
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, 0, "cbuf_new");
|
clicon_err(OE_UNIX, 0, "cbuf_new");
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@
|
||||||
|
|
||||||
/* restconf */
|
/* restconf */
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_root.h"
|
#include "restconf_root.h"
|
||||||
|
|
@ -89,7 +90,7 @@ api_well_known(clicon_handle h,
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
|
request_method = restconf_param_get(h, "REQUEST_METHOD");
|
||||||
if (strcmp(request_method, "GET") != 0){
|
if (strcmp(request_method, "GET") != 0){
|
||||||
restconf_method_notallowed(req, "GET");
|
restconf_method_notallowed(req, "GET");
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -265,7 +266,7 @@ api_data(clicon_handle h,
|
||||||
char *request_method;
|
char *request_method;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
|
request_method = restconf_param_get(h, "REQUEST_METHOD");
|
||||||
clicon_debug(1, "%s method:%s", __FUNCTION__, request_method);
|
clicon_debug(1, "%s method:%s", __FUNCTION__, request_method);
|
||||||
if (strcmp(request_method, "OPTIONS")==0)
|
if (strcmp(request_method, "OPTIONS")==0)
|
||||||
retval = api_data_options(h, req);
|
retval = api_data_options(h, req);
|
||||||
|
|
@ -355,7 +356,7 @@ api_root_restconf(clicon_handle h,
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
|
request_method = restconf_param_get(h, "REQUEST_METHOD");
|
||||||
path = restconf_uripath(h);
|
path = restconf_uripath(h);
|
||||||
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
|
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
|
||||||
/* Get media for output (proactive negotiation) RFC7231 by using
|
/* Get media for output (proactive negotiation) RFC7231 by using
|
||||||
|
|
@ -363,7 +364,7 @@ api_root_restconf(clicon_handle h,
|
||||||
* operation POST, etc
|
* operation POST, etc
|
||||||
* If accept is * default is yang-json
|
* If accept is * default is yang-json
|
||||||
*/
|
*/
|
||||||
if ((media_str = clixon_restconf_param_get(h, "HTTP_ACCEPT")) == NULL){
|
if ((media_str = restconf_param_get(h, "HTTP_ACCEPT")) == NULL){
|
||||||
// retval = restconf_unsupported_media(r);
|
// retval = restconf_unsupported_media(r);
|
||||||
// goto done;
|
// goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@
|
||||||
#include <fcgiapp.h> /* Need to be after clixon_xml.h due to attribute format */
|
#include <fcgiapp.h> /* Need to be after clixon_xml.h due to attribute format */
|
||||||
|
|
||||||
#include "restconf_lib.h"
|
#include "restconf_lib.h"
|
||||||
|
#include "restconf_handle.h"
|
||||||
#include "restconf_api.h"
|
#include "restconf_api.h"
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_stream.h"
|
#include "restconf_stream.h"
|
||||||
|
|
@ -376,7 +377,7 @@ api_stream(clicon_handle h,
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
path = restconf_uripath(h);
|
path = restconf_uripath(h);
|
||||||
query = clixon_restconf_param_get(h, "QUERY_STRING");
|
query = restconf_param_get(h, "QUERY_STRING");
|
||||||
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
|
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
|
||||||
if ((pvec = clicon_strsep(path, "/", &pn)) == NULL)
|
if ((pvec = clicon_strsep(path, "/", &pn)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ example_restconf_credentials(clicon_handle h,
|
||||||
if (basic_auth==0)
|
if (basic_auth==0)
|
||||||
goto ok;
|
goto ok;
|
||||||
/* At this point in the code we must use HTTP basic authentication */
|
/* At this point in the code we must use HTTP basic authentication */
|
||||||
if ((auth = clixon_restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL)
|
if ((auth = restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (strlen(auth) < strlen("Basic "))
|
if (strlen(auth) < strlen("Basic "))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
*
|
*
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
This file is part of CLIXON.
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ struct clicon_hash {
|
||||||
typedef struct clicon_hash *clicon_hash_t;
|
typedef struct clicon_hash *clicon_hash_t;
|
||||||
|
|
||||||
clicon_hash_t *clicon_hash_init (void);
|
clicon_hash_t *clicon_hash_init (void);
|
||||||
void clicon_hash_free (clicon_hash_t *);
|
int clicon_hash_free (clicon_hash_t *);
|
||||||
clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key);
|
clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key);
|
||||||
void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
|
void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
|
||||||
clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
|
clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
|
||||||
|
|
|
||||||
|
|
@ -93,12 +93,9 @@ clicon_data_get(clicon_handle h,
|
||||||
{
|
{
|
||||||
clicon_hash_t *cdat = clicon_data(h);
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
|
||||||
if (val == NULL){
|
|
||||||
clicon_err(OE_CFG, EINVAL, "%s val is NULL", __FUNCTION__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (clicon_hash_lookup(cdat, (char*)name) == NULL)
|
if (clicon_hash_lookup(cdat, (char*)name) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (val)
|
||||||
*val = clicon_hash_value(cdat, (char*)name, NULL);
|
*val = clicon_hash_value(cdat, (char*)name, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -716,4 +713,3 @@ clicon_session_id_set(clicon_handle h,
|
||||||
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
|
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
*
|
*
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
|
Copyright (C) 2017-2019 Olof Hagsand
|
||||||
|
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
This file is part of CLIXON.
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
|
@ -81,6 +83,7 @@
|
||||||
* XXX: put ch_stream under ch_data
|
* XXX: put ch_stream under ch_data
|
||||||
* @see struct cli_handle
|
* @see struct cli_handle
|
||||||
* @see struct backend_handle
|
* @see struct backend_handle
|
||||||
|
* @see struct restconf_handle
|
||||||
*/
|
*/
|
||||||
struct clicon_handle {
|
struct clicon_handle {
|
||||||
int ch_magic; /* magic (HDR) */
|
int ch_magic; /* magic (HDR) */
|
||||||
|
|
@ -157,7 +160,6 @@ clicon_handle_exit(clicon_handle h)
|
||||||
clicon_hash_free(ha);
|
clicon_hash_free(ha);
|
||||||
if ((ha = clicon_data(h)) != NULL)
|
if ((ha = clicon_data(h)) != NULL)
|
||||||
clicon_hash_free(ha);
|
clicon_hash_free(ha);
|
||||||
|
|
||||||
if ((ha = clicon_db_elmnt(h)) != NULL)
|
if ((ha = clicon_db_elmnt(h)) != NULL)
|
||||||
clicon_hash_free(ha);
|
clicon_hash_free(ha);
|
||||||
stream_delete_all(h, 1);
|
stream_delete_all(h, 1);
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,10 @@ clicon_hash_init(void)
|
||||||
/*! Free hash table.
|
/*! Free hash table.
|
||||||
*
|
*
|
||||||
* @param[in] hash Hash table
|
* @param[in] hash Hash table
|
||||||
* @retval void
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
clicon_hash_free(clicon_hash_t *hash)
|
clicon_hash_free(clicon_hash_t *hash)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -147,6 +148,7 @@ clicon_hash_free(clicon_hash_t *hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(hash);
|
free(hash);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Find hash key.
|
/*! Find hash key.
|
||||||
|
|
@ -189,6 +191,10 @@ clicon_hash_value(clicon_hash_t *hash,
|
||||||
{
|
{
|
||||||
clicon_hash_t h;
|
clicon_hash_t h;
|
||||||
|
|
||||||
|
if (hash == NULL){
|
||||||
|
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
h = clicon_hash_lookup(hash, key);
|
h = clicon_hash_lookup(hash, key);
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
return NULL; /* OK, key not found */
|
return NULL; /* OK, key not found */
|
||||||
|
|
@ -218,6 +224,10 @@ clicon_hash_add(clicon_hash_t *hash,
|
||||||
clicon_hash_t h;
|
clicon_hash_t h;
|
||||||
clicon_hash_t new = NULL;
|
clicon_hash_t new = NULL;
|
||||||
|
|
||||||
|
if (hash == NULL){
|
||||||
|
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/* Check NULL case */
|
/* Check NULL case */
|
||||||
if ((val == NULL && vlen != 0) ||
|
if ((val == NULL && vlen != 0) ||
|
||||||
(val != NULL && vlen == 0)){
|
(val != NULL && vlen == 0)){
|
||||||
|
|
@ -288,6 +298,10 @@ clicon_hash_del(clicon_hash_t *hash,
|
||||||
{
|
{
|
||||||
clicon_hash_t h;
|
clicon_hash_t h;
|
||||||
|
|
||||||
|
if (hash == NULL){
|
||||||
|
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
h = clicon_hash_lookup(hash, key);
|
h = clicon_hash_lookup(hash, key);
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -321,6 +335,10 @@ clicon_hash_keys(clicon_hash_t *hash,
|
||||||
char **tmp;
|
char **tmp;
|
||||||
char **keys = NULL;
|
char **keys = NULL;
|
||||||
|
|
||||||
|
if (hash == NULL){
|
||||||
|
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
*nkeys = 0;
|
*nkeys = 0;
|
||||||
for (bkt = 0; bkt < HASH_SIZE; bkt++) {
|
for (bkt = 0; bkt < HASH_SIZE; bkt++) {
|
||||||
h = hash[bkt];
|
h = hash[bkt];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue