1+ /**
2+ * \file src/plugins/intermediate/asn/asn.c
3+ * \author Adam Zvara <[email protected] > 4+ * \brief Configuration parser of ASN plugin (source file)
5+ * \date 2023
6+ */
7+
8+ /* Copyright (C) 2018 CESNET, z.s.p.o.
9+ *
10+ * Redistribution and use in source and binary forms, with or without
11+ * modification, are permitted provided that the following conditions
12+ * are met:
13+ * 1. Redistributions of source code must retain the above copyright
14+ * notice, this list of conditions and the following disclaimer.
15+ * 2. Redistributions in binary form must reproduce the above copyright
16+ * notice, this list of conditions and the following disclaimer in
17+ * the documentation and/or other materials provided with the
18+ * distribution.
19+ * 3. Neither the name of the Company nor the names of its contributors
20+ * may be used to endorse or promote products derived from this
21+ * software without specific prior written permission.
22+ *
23+ * ALTERNATIVELY, provided that this notice is retained in full, this
24+ * product may be distributed under the terms of the GNU General Public
25+ * License (GPL) version 2 or later, in which case the provisions
26+ * of the GPL apply INSTEAD OF those given above.
27+ *
28+ * This software is provided ``as is'', and any express or implied
29+ * warranties, including, but not limited to, the implied warranties of
30+ * merchantability and fitness for a particular purpose are disclaimed.
31+ * In no event shall the company or contributors be liable for any
32+ * direct, indirect, incidental, special, exemplary, or consequential
33+ * damages (including, but not limited to, procurement of substitute
34+ * goods or services; loss of use, data, or profits; or business
35+ * interruption) however caused and on any theory of liability, whether
36+ * in contract, strict liability, or tort (including negligence or
37+ * otherwise) arising in any way out of the use of this software, even
38+ * if advised of the possibility of such damage.
39+ *
40+ */
41+
42+ #include <stdlib.h>
43+ #include <unistd.h> // access()
44+ #include <errno.h>
45+ #include "config.h"
46+
47+ /*
48+ * <params>
49+ * <path>...</path>
50+ * </params>
51+ */
52+
53+ /** XML nodes */
54+ enum params_xml_nodes {
55+ ASN_PATH = 1 ,
56+ };
57+
58+ /** Definition of the \<params\> node */
59+ static const struct fds_xml_args args_params [] = {
60+ FDS_OPTS_ROOT ("params" ),
61+ FDS_OPTS_ELEM (ASN_PATH , "path" , FDS_OPTS_T_STRING , 0 ),
62+ FDS_OPTS_END
63+ };
64+
65+ /**
66+ * \brief Process \<params\> node
67+ * \param[in] ctx Plugin context
68+ * \param[in] root XML context to process
69+ * \param[in] cfg Parsed configuration
70+ * \return #IPX_OK on success
71+ * \return #IPX_ERR_FORMAT in case of failure
72+ */
73+ static int
74+ config_parser_root (ipx_ctx_t * ctx , fds_xml_ctx_t * root , struct asn_config * cfg )
75+ {
76+ (void ) ctx ;
77+ size_t path_len ;
78+
79+ const struct fds_xml_cont * content ;
80+ while (fds_xml_next (root , & content ) != FDS_EOC ) {
81+ switch (content -> id ) {
82+ case ASN_PATH :
83+ assert (content -> type == FDS_OPTS_T_STRING );
84+ path_len = strlen (content -> ptr_string );
85+ cfg -> db_path = strndup (content -> ptr_string , path_len );
86+ if (!cfg -> db_path ) {
87+ IPX_CTX_ERROR (ctx , "Memory allocation error (%s:%d)" , __FILE__ , __LINE__ );
88+ return IPX_ERR_FORMAT ;
89+ }
90+ break ;
91+ default :
92+ // Internal error
93+ assert (false);
94+ }
95+ }
96+
97+ return IPX_OK ;
98+ }
99+
100+ /**
101+ * \brief Check configuration parameters
102+ * \param[in] ctx Instance context
103+ * \param[in] cfg Parsed configuration
104+ * \return #IPX_OK on success (no fatal error)
105+ * \return #IPX_ERR_FORMAT in case of fatal failure
106+ */
107+ static int
108+ config_check (ipx_ctx_t * ctx , struct asn_config * cfg )
109+ {
110+ if (!cfg -> db_path ) {
111+ IPX_CTX_ERROR (ctx , "Path to database is not set" );
112+ return IPX_ERR_FORMAT ;
113+ }
114+
115+ // Check if database file exists and user has permission to read it
116+ int permissions = R_OK ; // File exists and user has read permissions
117+
118+ if (access (cfg -> db_path , permissions )) {
119+ switch (errno ) {
120+ case ENOENT :
121+ IPX_CTX_ERROR (ctx , "Could not find database file" );
122+ break ;
123+ case EACCES :
124+ IPX_CTX_ERROR (ctx , "Insufficient permissions on database file" );
125+ break ;
126+ default :
127+ IPX_CTX_ERROR (ctx , "Unexpected error occured (%s:%d)" , __FILE__ , __LINE__ );
128+ break ;
129+ }
130+ return IPX_ERR_FORMAT ;
131+ }
132+
133+ return IPX_OK ;
134+ }
135+
136+ struct asn_config *
137+ config_parse (ipx_ctx_t * ctx , const char * params )
138+ {
139+ struct asn_config * cfg = calloc (1 , sizeof (* cfg ));
140+ if (!cfg ) {
141+ IPX_CTX_ERROR (ctx , "Memory allocation error (%s:%d)" , __FILE__ , __LINE__ );
142+ return NULL ;
143+ }
144+
145+ // Create an XML parser
146+ fds_xml_t * parser = fds_xml_create ();
147+ if (!parser ) {
148+ IPX_CTX_ERROR (ctx , "Memory allocation error (%s:%d)" , __FILE__ , __LINE__ );
149+ free (cfg );
150+ return NULL ;
151+ }
152+ if (fds_xml_set_args (parser , args_params ) != IPX_OK ) {
153+ IPX_CTX_ERROR (ctx , "Failed to parse the description of an XML document!" , '\0' );
154+ fds_xml_destroy (parser );
155+ free (cfg );
156+ return NULL ;
157+ }
158+
159+ fds_xml_ctx_t * params_ctx = fds_xml_parse_mem (parser , params , true);
160+ if (params_ctx == NULL ) {
161+ IPX_CTX_ERROR (ctx , "Failed to parse the configuration: %s" , fds_xml_last_err (parser ));
162+ fds_xml_destroy (parser );
163+ free (cfg );
164+ return NULL ;
165+ }
166+
167+ // Parse parameters
168+ int rc = config_parser_root (ctx , params_ctx , cfg );
169+ fds_xml_destroy (parser );
170+ if (rc != IPX_OK ) {
171+ free (cfg );
172+ return NULL ;
173+ }
174+
175+ // Check validity of configuration
176+ if (config_check (ctx , cfg ) != IPX_OK ) {
177+ config_destroy (cfg );
178+ return NULL ;
179+ }
180+
181+ return cfg ;
182+ }
183+
184+ void
185+ config_destroy (struct asn_config * cfg )
186+ {
187+ free (cfg -> db_path );
188+ free (cfg );
189+ }
0 commit comments