1 /*
2  *
3   ***** BEGIN LICENSE BLOCK *****
4 
5   Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
6   Copyright (C) 2017-2019 Olof Hagsand
7   Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
8 
9   This file is part of CLIXON.
10 
11   Licensed under the Apache License, Version 2.0 (the "License");
12   you may not use this file except in compliance with the License.
13   You may obtain a copy of the License at
14 
15     http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22 
23   Alternatively, the contents of this file may be used under the terms of
24   the GNU General Public License Version 3 or later (the "GPL"),
25   in which case the provisions of the GPL are applicable instead
26   of those above. If you wish to allow use of your version of this file only
27   under the terms of the GPL, and not to allow others to
28   use your version of this file under the terms of Apache License version 2,
29   indicate your decision by deleting the provisions above and replace them with
30   the  notice and other provisions required by the GPL. If you do not delete
31   the provisions above, a recipient may use your version of this file under
32   the terms of any one of the Apache License version 2 or the GPL.
33 
34   ***** END LICENSE BLOCK *****
35  *
36  */
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <syslog.h>
42 #include <unistd.h>
43 #include <sys/stat.h>
44 #include <sys/time.h>
45 #include <sys/param.h>
46 #include <netinet/in.h>
47 #include <signal.h> /* matching strings */
48 
49 /* clicon */
50 #include <cligen/cligen.h>
51 #include <clixon/clixon.h>
52 #include <clixon/clixon_cli.h>
53 
54 
55 /*! Example cli function */
56 int
mycallback(clicon_handle h,cvec * cvv,cvec * argv)57 mycallback(clicon_handle h, cvec *cvv, cvec *argv)
58 {
59     int      retval = -1;
60     cxobj   *xret = NULL;
61     cg_var  *myvar;
62     cvec    *nsc = NULL;
63 
64     /* Access cligen callback variables */
65     myvar = cvec_find(cvv, "var"); /* get a cligen variable from vector */
66     fprintf(stderr, "%s: %d\n", __FUNCTION__, cv_int32_get(myvar)); /* get int value */
67     fprintf(stderr, "arg = %s\n", cv_string_get(cvec_i(argv,0))); /* get string value */
68 
69     if ((nsc = xml_nsctx_init(NULL, "urn:example:clixon")) == NULL)
70 	goto done;
71     /* Show eth0 interfaces config using XPATH */
72     if (clicon_rpc_get_config(h, NULL, "running",
73 			      "/interfaces/interface[name='eth0']",
74 			      nsc,
75 			      &xret) < 0)
76 	goto done;
77     clicon_xml2file_cb(stdout, xret, 0, 1, cligen_output);
78     retval = 0;
79  done:
80     if (nsc)
81 	xml_nsctx_free(nsc);
82     if (xret)
83 	xml_free(xret);
84     return retval;
85 }
86 
87 /*! Example "downcall", ie initiate an RPC to the backend */
88 int
example_client_rpc(clicon_handle h,cvec * cvv,cvec * argv)89 example_client_rpc(clicon_handle h,
90 		   cvec         *cvv,
91 		   cvec         *argv)
92 {
93     int        retval = -1;
94     cg_var    *cva;
95     cxobj     *xtop = NULL;
96     cxobj     *xrpc;
97     cxobj     *xret = NULL;
98     cxobj     *xerr;
99 
100     /* User supplied variable in CLI command */
101     cva = cvec_find(cvv, "a"); /* get a cligen variable from vector */
102     /* Create XML for example netconf RPC */
103     if (clixon_xml_parse_va(YB_NONE, NULL, &xtop, NULL,
104 			    "<rpc message-id=\"101\" xmlns=\"%s\" username=\"%s\">"
105 			    "<example xmlns=\"urn:example:clixon\"><x>%s</x></example></rpc>",
106 			    NETCONF_BASE_NAMESPACE,
107 			    clicon_username_get(h),
108 			    cv_string_get(cva)) < 0)
109 	goto done;
110     /* Skip top-level */
111     xrpc = xml_child_i(xtop, 0);
112     /* Send to backend */
113     if (clicon_rpc_netconf_xml(h, xrpc, &xret, NULL) < 0)
114 	goto done;
115     if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
116 	clixon_netconf_error(xerr, "Get configuration", NULL);
117 	goto done;
118     }
119     /* Print result */
120     clicon_xml2file_cb(stdout, xml_child_i(xret, 0), 0, 0, cligen_output);
121     fprintf(stdout,"\n");
122 
123     /* pretty-print:
124        xml2txt_cb(stdout, xml_child_i(xret, 0), cligen_output);
125     */
126     retval = 0;
127  done:
128     if (xret)
129 	xml_free(xret);
130     if (xtop)
131 	xml_free(xtop);
132     return retval;
133 }
134 
135 static clixon_plugin_api api = {
136     "example",          /* name */
137     clixon_plugin_init, /* init */
138     NULL,               /* start */
139     NULL,               /* exit */
140     .ca_prompt=NULL,    /* cli_prompthook_t */
141     .ca_suspend=NULL,   /* cligen_susp_cb_t */
142     .ca_interrupt=NULL, /* cligen_interrupt_cb_t */
143 };
144 
145 /*! CLI plugin initialization
146  * @param[in]  h    Clixon handle
147  * @retval     NULL Error with clicon_err set
148  * @retval     api  Pointer to API struct
149  */
150 clixon_plugin_api *
clixon_plugin_init(clicon_handle h)151 clixon_plugin_init(clicon_handle h)
152 {
153     struct timeval tv;
154 
155     gettimeofday(&tv, NULL);
156     srandom(tv.tv_usec);
157 
158     return &api;
159 }
160 
161 /*! Translate function from an original value to a new.
162  * In this case, assume string and increment characters, eg HAL->IBM
163  */
164 int
incstr(cligen_handle h,cg_var * cv)165 incstr(cligen_handle h,
166        cg_var       *cv)
167 {
168     char *str;
169     int i;
170 
171     if (cv_type_get(cv) != CGV_STRING)
172 	return 0;
173     str = cv_string_get(cv);
174     for (i=0; i<strlen(str); i++)
175 	str[i]++;
176     return 0;
177 }
178