Skip to content

Commit

Permalink
CLI generic pipe callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
olofhagsand committed Dec 6, 2024
1 parent 69eaf98 commit c24c38d
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Expected: January 2025

### Features

* New: CLI generic pipe callbacks
* Add scripts in `CLICON_CLI_PIPE_DIR`
* New: [feature request: support xpath functions for strings](https://github.com/clicon/clixon/issues/556)
* Added: re-match, substring, string, string-length, translate, substring-before, substring-after, starts-with
* Added support for system-only-config data
Expand All @@ -26,6 +28,7 @@ Expected: January 2025
* New `ca_system_only` backend callback for reading system-only data
* New `clixon-config@2024-11-01.yang` revision
* Changed: `CLICON_NETCONF_DUPLICATE_ALLOW` to not only check but remove duplicates
* Added: `CLICON_CLI_PIPE_DIR`
* Added: `CLICON_XMLDB_SYSTEM_ONLY_CONFIG`

### C/CLI-API changes on existing features
Expand Down
2 changes: 0 additions & 2 deletions apps/cli/cli_auto.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@
#include <stdarg.h>
#include <time.h>
#include <ctype.h>

#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
#include <arpa/inet.h>
#include <netinet/in.h>
Expand Down
6 changes: 4 additions & 2 deletions apps/cli/cli_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
#include <arpa/inet.h>
#include <netinet/in.h>
Expand Down Expand Up @@ -807,7 +806,8 @@ cli_set_mode(clixon_handle h,
* @param[in] argv Function arguments
* @retval 0 OK, returns the exit code of the program
* @retval -1 Error
*
* @note utility, should probably not be in lib
* @see cli_start_shell
*/
int
cli_start_program(clixon_handle h,
Expand Down Expand Up @@ -926,6 +926,8 @@ cli_start_program(clixon_handle h,
* @param[in] argv [<shell>], defaults to "sh"
* @retval 0 OK
* @retval -1 Error
* @note utility, should probably not be in lib
* @see cli_start_program
*/
int
cli_start_shell(clixon_handle h,
Expand Down
1 change: 0 additions & 1 deletion apps/cli/cli_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
#include <errno.h>
#include <assert.h>
#include <dlfcn.h>
#include <dirent.h>
#include <grp.h>
#include <signal.h>
#include <sys/types.h>
Expand Down
1 change: 0 additions & 1 deletion apps/cli/cli_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
Expand Down
82 changes: 72 additions & 10 deletions apps/cli/cli_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@
#include <stdarg.h>
#include <time.h>
#include <ctype.h>

#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
#include <arpa/inet.h>
#include <netinet/in.h>
Expand All @@ -71,24 +69,25 @@
#include <clixon/clixon.h>

#include "clixon_cli_api.h"
#include "cli_pipe.h"

/* General-purpose pipe output function
*
* @param[in] h Clixon handle
* @param[in] cmd Command to exec
* @param[in] cmd Command/file to exec
* @param[in] option Option to command (or NULL)
* @param[in] value Command argument value (or NULL)
*/
int
static int
pipe_arg_fn(clixon_handle h,
char *cmd,
char *option,
char *value)
{
int retval = -1;
struct stat fstat;
char **argv = NULL;
int i;
int retval = -1;
struct stat fstat;
char **argv = NULL;
int i;

if (cmd == NULL || strlen(cmd) == 0){
clixon_err(OE_PLUGIN, EINVAL, "cmd '%s' NULL or empty", cmd);
Expand All @@ -108,8 +107,10 @@ pipe_arg_fn(clixon_handle h,
}
i = 0;
argv[i++] = cmd;
argv[i++] = option;
argv[i++] = value;
if (option) {
argv[i++] = option;
argv[i++] = value;
}
argv[i++] = NULL;
retval = execv(cmd, argv);
done:
Expand Down Expand Up @@ -198,6 +199,7 @@ pipe_wc_fn(clixon_handle h,
if (cvec_len(argv) != 1){
clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <NUM>", cvec_len(argv));
goto done;

}
if ((cv = cvec_i(argv, 0)) != NULL &&
(str = cv_string_get(cv)) != NULL &&
Expand Down Expand Up @@ -392,6 +394,66 @@ pipe_save_file(clixon_handle h,
return retval;
}

/*! pipe function: start script
*
* @param[in] h Clixon handle
* @param[in] cvv Vector of cli string and instantiated variables
* @param[in] argv String vector of options. Format:
* name Name of cv containing script filename
* @retval 0 OK
* @retval -1 Error
* @code
* format("Generic format by callback") <callback:string>("Name of generic format"),
* pipe_generic_callback("callback");
* @endcode
*/
int
pipe_generic(clixon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
char *cvname;
cg_var *cv;
char *dir;
char *filename;
char *script = NULL;
cbuf *cb = NULL;

if (cvec_len(argv) != 1) {
clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <script>", cvec_len(argv));
goto done;
}
if ((cvname = cv_string_get(cvec_i(argv, 0))) != NULL) {
if ((cv = cvec_find(cvv, cvname)) != NULL){
if ((script = cv_string_get(cv)) == NULL){
clixon_err(OE_PLUGIN, EINVAL, "cv name is empty");
goto done;
}
}
}
if (script == NULL || strlen(script) == 0)
goto ok;
if ((dir = clicon_option_str(h, "CLICON_CLI_PIPE_DIR")) == NULL){
clixon_err(OE_UNIX, 0, "CLICON_CLI_PIPE_DIR not set");
goto done;
}
if ((cb = cbuf_new()) == NULL){
clixon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cb, "%s/%s", dir, script);
filename = cbuf_get(cb);
if (pipe_arg_fn(h, filename, NULL, NULL) < 0)
goto done;
ok:
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}

/*! Test cli callback calls cligen_output with output lines as given by function arguments
*
* Only for test or debugging to generate output to eg cligen_output scrolling
Expand Down
48 changes: 48 additions & 0 deletions apps/cli/cli_pipe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
Copyright (C) 2020-2022 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 _CLI_PIPE_H_
#define _CLI_PIPE_H_

int pipe_grep_fn(clixon_handle h, cvec *cvv, cvec *argv);
int pipe_wc_fn(clixon_handle h, cvec *cvv, cvec *argv);
int pipe_tail_fn(clixon_handle h, cvec *cvv, cvec *argv);
int pipe_showas_fn(clixon_handle h, cvec *cvv, cvec *argv);
int pipe_save_file(clixon_handle h, cvec *cvv, cvec *argv);
int pipe_generic(clixon_handle h, cvec *cvv, cvec *argv);

#endif /* _CLI_PIPE_H_ */
69 changes: 67 additions & 2 deletions apps/cli/cli_show.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
#include <pwd.h>
#include <inttypes.h>
Expand Down Expand Up @@ -611,6 +610,72 @@ expand_yang_list(void *h,
return retval;
}

/*! Completion callback of variable for file directory
*
* Returns an expand-type list of commands as used by cligen 'expand'
* functionality.
*
* Assume callback given in a cligen spec: a <x:int expand_dbvar("db" "<xmlkeyfmt>")
* @param[in] h clicon handle
* @param[in] name Name of this function (eg "expand_dbvar")
* @param[in] cvv The command so far. Eg: cvec [0]:"a 5 b"; [1]: x=5;
* @param[in] argv Arguments given at the callback:
* <dir> File directory
* <regex> Regexp of files to show
* @param[out] commands vector of function pointers to callback functions
* @param[out] helptxt vector of pointers to helptexts
* @retval 0 OK
* @retval -1 Error
* @code
* <callback:string expand_dir("/usr/local/var/pipedir", "\.sh$")>("comment"), Command;
* @endcode
* @see expand_dbvar
*/
int
expand_dir(void *h,
char *name,
cvec *cvv,
cvec *argv,
cvec *commands,
cvec *helptexts)
{
int retval = -1;
int argc = 0;
cg_var *cv;
char *dir;
char *regexp = NULL;
struct dirent *dp;
int ndp;
int i;

if (argv == NULL || cvec_len(argv) < 1 || cvec_len(argv) > 2){
clixon_err(OE_PLUGIN, EINVAL, "requires arguments: <dir> [<regexp>]");
goto done;
}
if ((cv = cvec_i(argv, argc++)) == NULL){
clixon_err(OE_PLUGIN, 0, "Error when accessing argument <schemanode>");
goto done;
}
dir = cv_string_get(cv);
if (cvec_len(argv) > argc){
if ((cv = cvec_i(argv, argc++)) == NULL){
clixon_err(OE_PLUGIN, 0, "Error when accessing argument <schemanode>");
goto done;
}
regexp = cv_string_get(cv);
}
if ((ndp = clicon_file_dirent(dir, &dp, regexp, S_IFREG)) < 0)
goto done;
for (i = 0; i < ndp; i++) {
cvec_add_string(commands, NULL, dp[i].d_name);
}
retval = 0;
done:
if (dp)
free(dp);
return retval;
}

/*! CLI callback show yang spec. If arg given matches yang argument string
*
* @param[in] h Clixon handle
Expand Down Expand Up @@ -1080,7 +1145,7 @@ cli_show_version(clixon_handle h,
* [<mt-point>] Optional YANG path-arg/xpath from mount-point
* <dbname> Name of datastore, such as "running"
* -- from here optional:
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum), default: xml
* <format> text|xml|json|cli|netconf|default (see format_enum), default: xml
* <pretty> true|false: pretty-print or not
* <state> true|false: also print state
* <default> Retrieval mode: report-all, trim, explicit, report-all-tagged,
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/clixon_cli_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
***** END LICENSE BLOCK *****
* Note, this is a CLICON API file, only exprorted function prototypes should appear here
* Note, this is a CLICON API file, only exported function prototypes should appear here
*/

#ifndef _CLIXON_CLI_API_H_
Expand Down
Loading

0 comments on commit c24c38d

Please sign in to comment.