libamxo  4.3.4
Object Definition Language (ODL) parsing
amxo_parser_dm_utils.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 #ifndef _GNU_SOURCE
55 #define _GNU_SOURCE
56 #endif
57 
58 #include "amxo_parser_priv.h"
59 #include "amxo_parser.tab.h"
60 #include "amxo_parser_hooks_priv.h"
61 
62 static int object_actions[] = {
63  action_any,
64  action_object_read, // action_read,
65  action_object_write, // action_write
66  action_object_validate, // action_validate
67  action_object_list, // action_list
68  action_object_describe, // action_describe
69  action_object_add_inst, // action_add_inst
70  action_object_del_inst, // action_del_inst
71  action_object_destroy, // action_destroy
72  action_invalid, // action_translate
73  action_invalid, // action apply
74 };
75 
76 static int param_actions[] = {
77  action_any,
78  action_param_read, // action_read,
79  action_param_write, // action_write
80  action_param_validate, // action_validate
81  action_invalid, // action_list
82  action_param_describe, // action_describe
83  action_invalid, // action_add_inst
84  action_invalid, // action_del_inst
85  action_param_destroy, // action_destroy
86  action_invalid, // action_translate
87  action_invalid, // action_apply
88 };
89 
90 static int sync_actions[] = {
91  action_invalid,
92  action_invalid, // action_read,
93  action_invalid, // action_write
94  action_invalid, // action_validate
95  action_invalid, // action_list
96  action_invalid, // action_describe
97  action_invalid, // action_add_inst
98  action_invalid, // action_del_inst
99  action_invalid, // action_destroy
100  action_translate, // action_translate
101  action_apply, // action_apply
102 };
103 
105  event_id_t event) {
106  event_t* e = (event_t*) calloc(1, sizeof(event_t));
107  e->id = event;
108  e->path = amxd_object_get_path(pctx->object, AMXD_OBJECT_TERMINATE | AMXD_OBJECT_INDEXED);
109  amxc_var_init(&e->data);
110 
111  amxc_llist_append(&pctx->event_list, &e->it);
112 }
113 
114 static amxd_status_t amxo_cleanup_data(amxd_object_t* const object,
115  amxd_param_t* const param,
116  amxd_action_t reason,
117  UNUSED const amxc_var_t* const args,
118  UNUSED amxc_var_t* const retval,
119  void* priv) {
120  amxd_status_t status = amxd_status_ok;
121  amxc_var_t* data = (amxc_var_t*) priv;
122 
123  // action private data must not be removed when the action is used
124  // on derivced objects.
125  // only remove action data when the action is owned by the object or
126  // parameter on which the action is called.
127  if(reason == action_object_destroy) {
128  if(amxd_object_has_action_cb(object, reason, amxo_cleanup_data)) {
129  amxc_var_delete(&data);
130  amxd_object_set_action_cb_data(object, reason, amxo_cleanup_data, NULL);
131  }
132  } else {
133  if(amxd_param_has_action_cb(param, reason, amxo_cleanup_data)) {
134  amxc_var_delete(&data);
135  amxd_param_set_action_cb_data(param, reason, amxo_cleanup_data, NULL);
136  }
137  }
138 
139  return status;
140 }
141 
142 static amxd_status_t amxo_parser_set_param_action_impl(amxd_param_t* param,
143  amxd_action_t action,
144  amxd_action_fn_t fn,
145  amxc_var_t* data) {
146  amxd_status_t status = amxd_status_ok;
147 
148  status = amxd_param_add_action_cb(param, action, fn, data);
149  if((data != NULL) && (status == amxd_status_ok)) {
150  status = amxd_param_add_action_cb(param,
151  action_param_destroy,
153  data);
154  if(status != amxd_status_ok) {
155  amxd_param_remove_action_cb(param, action, fn);
156  }
157  }
158 
159  return status;
160 }
161 
162 static amxd_status_t amxo_parser_set_object_action_impl(amxd_object_t* object,
163  amxd_action_t action,
164  amxd_action_fn_t fn,
165  amxc_var_t* data) {
166  amxd_status_t status = amxd_status_ok;
167 
168  status = amxd_object_add_action_cb(object, action, fn, data);
169  if((data != NULL) && (status == amxd_status_ok)) {
170  status = amxd_object_add_action_cb(object,
171  action_object_destroy,
173  data);
174  if(status != amxd_status_ok) {
175  amxd_object_remove_action_cb(object, action, fn);
176  }
177  }
178 
179  return status;
180 }
181 
183  amxo_action_t action,
184  UNUSED const char* name,
185  UNUSED amxc_var_t* data) {
186  int retval = -1;
187  amxd_action_t dm_action = (amxd_action_t) sync_actions[action];
188  bool resolve = !amxo_parser_no_resolve(pctx) && pctx->resolved_fn != NULL;
189 
190  switch(dm_action) {
191  case action_translate:
192  if(resolve) {
194  (amxs_translation_cb_t) pctx->resolved_fn);
195  }
196  break;
197  case action_apply:
198  if(resolve) {
199  pctx->status = amxo_parser_sync_set_action(pctx,
200  (amxs_action_cb_t) pctx->resolved_fn);
201  }
202  break;
203  default:
204  pctx->status = amxd_status_invalid_action;
205  amxo_parser_msg(pctx, "Invalid synchronisation action (action id = %d)", action);
206  break;
207  }
208 
209  retval = pctx->status == amxd_status_ok? 0:-1;
210 
211  return retval;
212 }
213 
215  amxo_action_t action,
216  const char* name,
217  amxc_var_t* data) {
218  int retval = -1;
219  amxd_action_t dm_action = (amxd_action_t) param_actions[action];
220  bool resolve = !amxo_parser_no_resolve(pctx) && pctx->resolved_fn != NULL;
221 
222  if(dm_action == action_invalid) {
223  pctx->status = amxd_status_invalid_action;
224  amxo_parser_msg(pctx, "Invalid parameter action (action id = %d)", action);
225  goto exit;
226  }
227  if(resolve) {
229  dm_action,
230  (amxd_action_fn_t) pctx->resolved_fn,
231  data);
232  }
233 
234  if(pctx->status == amxd_status_ok) {
235  amxo_hooks_set_action_cb(pctx, pctx->object, pctx->param, dm_action, name, data);
236  retval = 0;
237  } else {
238  amxo_parser_msg(pctx, "Invalid parameter action (action id = %d)", action);
239  }
240 
241 exit:
242  return retval;
243 }
244 
246  amxo_action_t action,
247  const char* name,
248  amxc_var_t* data) {
249  int retval = -1;
250  amxd_action_t dm_action = (amxd_action_t) object_actions[action];
251  bool resolve = !amxo_parser_no_resolve(pctx) && pctx->resolved_fn != NULL;
252 
253  if(dm_action == action_invalid) {
254  pctx->status = amxd_status_invalid_action;
255  amxo_parser_msg(pctx, "Invalid object action (action id = %d)", action);
256  goto exit;
257  }
258  if(resolve) {
260  dm_action,
261  (amxd_action_fn_t) pctx->resolved_fn,
262  data);
263  }
264 
265  if(pctx->status == amxd_status_ok) {
266  amxo_hooks_set_action_cb(pctx, pctx->object, NULL, dm_action, name, data);
267  retval = 0;
268  } else {
269  amxo_parser_msg(pctx, "Invalid object (action id = %d)", action);
270  }
271 
272 exit:
273  return retval;
274 }
275 
276 static int64_t amxo_attr_2_object_attr(int64_t attributes) {
277  int64_t obj_attrs = 0;
278  if(SET_BIT(attr_readonly) & attributes) {
279  obj_attrs |= SET_BIT(amxd_oattr_read_only);
280  }
281  if(SET_BIT(attr_persistent) & attributes) {
282  obj_attrs |= SET_BIT(amxd_oattr_persistent);
283  }
284  if(SET_BIT(attr_private) & attributes) {
285  obj_attrs |= SET_BIT(amxd_oattr_private);
286  }
287  if(SET_BIT(attr_protected) & attributes) {
288  obj_attrs |= SET_BIT(amxd_oattr_protected);
289  }
290  return obj_attrs;
291 }
292 
293 static amxd_object_t* amxo_parser_new_object(amxo_parser_t* pctx,
294  amxd_dm_t* dm,
295  const char* name,
296  int64_t oattrs,
297  amxd_object_type_t type) {
298  amxd_object_t* object = NULL;
299  const char* type_name = type == amxd_object_mib ? "mib" : "object";
300 
301  pctx->status = amxd_object_new(&object, type, name);
302  if(pctx->status != amxd_status_ok) {
303  amxo_parser_msg(pctx, "Failed to create %s %s", type_name, name);
304  goto exit;
305  }
306  if(type == amxd_object_mib) {
307  pctx->status = amxd_dm_store_mib(dm, object);
308  } else {
309  amxd_object_set_attrs(object, oattrs, true);
310  pctx->status = amxd_object_add_object(pctx->object, object);
311  }
312 
313 exit:
314  return object;
315 }
316 
318  const char* name,
319  amxd_object_type_t type) {
320  int retval = 0;
321  const char* type_name = type == amxd_object_mib ? "mib" : "object";
322  if(amxo_parser_check_config(pctx,
323  "define-behavior.existing-object",
324  "update")) {
325  pctx->status = amxd_status_ok;
326  goto exit;
327  }
328  amxo_parser_msg(pctx, "Duplicate %s %s", type_name, name);
329  pctx->status = amxd_status_duplicate;
330  retval = -1;
331 
332 exit:
333  return retval;
334 }
335 
336 static amxd_object_t* amxo_parser_can_update_instance(amxo_parser_t* pctx,
337  uint32_t index,
338  const char* name,
339  amxc_var_t* params) {
340  amxd_object_t* object = NULL;
341  if(!amxo_parser_check_config(pctx,
342  "populate-behavior.duplicate-instance",
343  "update")) {
344  amxo_parser_msg(pctx, "Duplicate instance");
345  goto exit;
346  }
347  if(params != NULL) {
348  amxp_expr_t* expr = NULL;
349  amxd_object_new_key_expr(pctx->object, &expr, params);
350  object = amxd_object_find_instance(pctx->object, expr);
351  amxp_expr_delete(&expr);
352  }
353  if(object == NULL) {
354  object = amxd_object_get_instance(pctx->object, name, index);
355  }
356 
357 exit:
358  return object;
359 }
360 
362  amxp_signal_mngr_t* const sig_mngr,
363  const char* const signal_name,
364  bool signal_is_regexp,
365  const char* const expression,
366  amxp_slot_fn_t fn) {
367  int retval = 0;
368 
369  if(signal_is_regexp) {
370  retval = amxp_slot_connect_filtered(sig_mngr,
371  signal_name,
372  expression,
373  fn,
374  pctx->resolved_fn_name);
375  } else {
376  retval = amxp_slot_connect(sig_mngr,
377  signal_name,
378  expression,
379  fn,
380  pctx->resolved_fn_name);
381  }
382  if(retval != 0) {
383  retval = -1;
384  pctx->status = amxd_status_invalid_value;
385  if(expression != NULL) {
386  amxo_parser_msg(pctx, "Subscribe failed : %s", expression);
387  } else {
388  amxo_parser_msg(pctx, "Subscribe failed : %s", signal_name);
389  }
390  amxc_string_delete(&pctx->resolved_fn_name);
391  } else {
392  amxc_llist_append(&pctx->function_names, &pctx->resolved_fn_name->it);
393  pctx->resolved_fn_name = NULL;
394  }
395 
396  pctx->resolved_fn_name = NULL;
397  return retval;
398 }
399 
400 static amxd_object_t* amxd_parser_add_instance_msg(amxo_parser_t* pctx,
401  uint32_t index,
402  const char* name,
403  amxd_object_t* object,
404  amxc_var_t* params) {
405  switch(pctx->status) {
406  case amxd_status_ok:
407  break;
408  case amxd_status_invalid_name:
409  amxo_parser_msg(pctx, "Failed to create instance %s - invalid name", name);
410  break;
411  case amxd_status_invalid_type:
412  amxo_parser_msg(pctx,
413  "Failed to create instance %s - parent is not a template object",
414  name);
415  break;
416  case amxd_status_duplicate:
417  object = amxo_parser_can_update_instance(pctx, index, name, params);
418  if(object != NULL) {
419  pctx->status = amxd_status_ok;
420  }
421  break;
422  case amxd_status_missing_key:
423  amxo_parser_msg(pctx, "Failed to create instance %s - missing key(s)", name);
424  break;
425  default:
426  amxo_parser_msg(pctx, "Failed to create instance %s", name);
427  break;
428  }
429 
430  return object;
431 }
432 
433 static void amxo_parser_build_path_expr(amxd_object_t* object, amxc_string_t* expr) {
434  bool regexp = false;
435 
436  if(amxd_object_get_type(object) == amxd_object_template) {
437  regexp = true;
438  amxc_string_prependf(expr,
439  "%s\\.[0-9]*.{0,1}",
440  amxd_object_get_name(object, AMXD_OBJECT_NAMED));
441  } else {
442  amxc_string_prependf(expr,
443  "%s\\.",
444  amxd_object_get_name(object, AMXD_OBJECT_NAMED));
445  }
446  object = amxd_object_get_parent(object);
447 
448  while(object != NULL && amxd_object_get_parent(object) != NULL) {
449  switch(amxd_object_get_type(object)) {
450  case amxd_object_template:
451  regexp = true;
452  amxc_string_prependf(expr,
453  "%s\\.[0-9]+\\.",
454  amxd_object_get_name(object, AMXD_OBJECT_NAMED));
455  break;
456  case amxd_object_singleton:
457  amxc_string_prependf(expr,
458  "%s\\.",
459  amxd_object_get_name(object, AMXD_OBJECT_NAMED));
460  break;
461  default:
462  break;
463  }
464  object = amxd_object_get_parent(object);
465  }
466 
467  if(regexp) {
468  amxc_string_prepend(expr, "(path matches '^", 16);
469  amxc_string_append(expr, "$')", 3);
470  } else {
471  amxc_string_replace(expr, "\\", "", UINT32_MAX);
472  amxc_string_prepend(expr, "(path == '", 10);
473  amxc_string_append(expr, "')", 2);
474  }
475 }
476 
478  const char* path,
479  const char* check) {
480  amxc_var_t* option = amxc_var_get_path(&pctx->config,
481  path,
482  AMXC_VAR_FLAG_DEFAULT);
483  const char* value = NULL;
484  value = amxc_var_constcast(cstring_t, option);
485 
486  if(value == NULL) {
487  value = "error";
488  }
489 
490  return strcmp(value, check) == 0;
491 }
492 
493 void amxo_parser_free_event(amxc_llist_it_t* it) {
494  event_t* e = amxc_container_of(it, event_t, it);
495  amxc_var_clean(&e->data);
496  free(e);
497 }
498 
500  int64_t attributes,
501  int64_t bitmask) {
502  bool retval = false;
503  int attr_mask = ~bitmask;
504 
505  int check_attr = attributes | attr_mask;
506  pctx->status = (check_attr != attr_mask) ? amxd_status_ok : amxd_status_invalid_attr;
507  retval = (check_attr != attr_mask);
508  if(!retval) {
509  amxo_parser_msg(pctx, "Invalid attributes given");
510  }
511  return retval;
512 }
513 
514 bool amxo_parser_set_object_attrs(amxo_parser_t* pctx, uint64_t attr, bool enable) {
515  int64_t oattrs = amxo_attr_2_object_attr(attr);
516  amxd_object_set_attrs(pctx->object, oattrs, enable);
517  return true;
518 }
519 
521  const char* name,
522  int64_t attr_bitmask,
523  amxd_object_type_t type) {
524  amxd_object_t* object = NULL;
525  amxc_string_t res_name;
526  int64_t oattrs = amxo_attr_2_object_attr(attr_bitmask);
527  int retval = -1;
528  amxd_dm_t* dm = amxd_object_get_dm(pctx->object);
529 
530  amxc_string_init(&res_name, 0);
531 
532  if(amxc_string_set_resolved(&res_name, name, &pctx->config) > 0) {
533  name = amxc_string_get(&res_name, 0);
534  }
535 
536  pctx->status = amxd_status_ok;
537  if(type == amxd_object_mib) {
538  object = amxd_dm_get_mib(dm, name);
539  } else {
540  object = amxd_object_findf(pctx->object, "%s", name);
541  }
542  if(object == NULL) {
543  object = amxo_parser_new_object(pctx, dm, name, oattrs, type);
544  when_null(object, exit);
545  } else {
546  retval = amxo_parser_can_update_object(pctx, name, type);
547  when_true(retval < 0, exit);
548  amxd_object_set_attrs(object, oattrs, true);
549  }
550 
551  amxo_hooks_create_object(pctx, name, oattrs, type);
552 
553  amxc_astack_push(&pctx->object_stack, pctx->object);
554  pctx->object = object;
556  retval = 0;
557 
558 exit:
559  amxc_string_clean(&res_name);
560  return retval;
561 }
562 
564  uint32_t index,
565  const char* name,
566  amxc_var_t* params) {
567  amxd_object_t* object = NULL;
568  amxd_object_t* parent_obj = pctx->object;
569  bool retval = false;
570  amxc_string_t res_name;
571  amxc_string_init(&res_name, 0);
572 
573  if(amxc_string_set_resolved(&res_name, name, &pctx->config) > 0) {
574  name = amxc_string_get(&res_name, 0);
575  }
576 
577  pctx->status = amxd_object_add_instance(&object,
578  parent_obj,
579  name,
580  index,
581  params);
582  object = amxd_parser_add_instance_msg(pctx, index, name, object, params);
583  when_null(object, exit);
584  when_failed(pctx->status, exit);
585  amxo_hooks_add_instance(pctx, amxd_object_get_index(object),
586  amxd_object_get_name(object, AMXD_OBJECT_NAMED));
587  amxc_astack_push(&pctx->object_stack, pctx->object);
588  pctx->object = object;
590  retval = true;
591 
592 exit:
593  amxc_string_clean(&res_name);
594  amxc_var_delete(&params);
595  return retval;
596 }
597 
599  const char* path) {
600  amxd_object_t* object = NULL;
601  bool retval = false;
602  amxc_string_t res_path;
603  amxc_string_init(&res_path, 0);
604 
605  if(amxc_string_set_resolved(&res_path, path, &pctx->config) > 0) {
606  path = amxc_string_get(&res_path, 0);
607  }
608 
609  pctx->status = amxd_status_ok;
610  object = amxd_object_findf(pctx->object, "%s", path);
611  if(object == NULL) {
612  char* parent_path = amxd_object_get_path(pctx->object, AMXD_OBJECT_NAMED);
613  amxo_parser_msg(pctx,
614  "Object %s not found (start searching from \"%s\")",
615  path,
616  parent_path == NULL ? "root" : parent_path);
617  free(parent_path);
618  pctx->status = amxd_status_object_not_found;
619  goto exit;
620  }
621 
622  amxo_hooks_select_object(pctx, path);
623 
624  amxc_astack_push(&pctx->object_stack, pctx->object);
625  pctx->object = object;
627  retval = true;
628 
629 exit:
630  amxc_string_clean(&res_path);
631  return retval;
632 }
633 
635  bool retval = false;
636  amxd_object_type_t type = amxd_object_get_type(pctx->object);
637  const char* type_name = (type == amxd_object_mib) ? "mib" : "object";
638  amxc_var_t args;
639 
640  pctx->status = amxd_object_validate(pctx->object, 0);
641 
642  amxc_var_init(&args);
643  amxc_var_set_type(&args, AMXC_VAR_ID_HTABLE);
644 
645  if(pctx->status != amxd_status_ok) {
646  amxo_parser_msg(pctx, "%s %s validation failed",
647  type_name,
648  amxd_object_get_name(pctx->object, AMXD_OBJECT_NAMED));
649  goto exit;
650  }
651 
652  amxd_dm_invoke_action(pctx->object, NULL, action_object_write, &args, NULL);
653  amxo_hooks_end_object(pctx);
654 
655  pctx->object = (amxd_object_t*) amxc_astack_pop(&pctx->object_stack);
656 
657  retval = true;
658 
659 exit:
660  amxc_var_clean(&args);
661  return retval;
662 }
663 
665  const char* param_name) {
666  bool retval = false;
667  amxc_string_t res_param_name;
668  amxc_string_init(&res_param_name, 0);
669 
670  if(amxc_string_set_resolved(&res_param_name, param_name, &pctx->config) > 0) {
671  param_name = amxc_string_get(&res_param_name, 0);
672  }
673 
674  pctx->status = amxd_object_set_counter(pctx->object, param_name);
675  if(pctx->status != amxd_status_ok) {
676  char* path = amxd_object_get_path(pctx->object, AMXD_OBJECT_NAMED);
677  amxo_parser_msg(pctx,
678  "Failed to to set instance counter %s on %s",
679  param_name,
680  path);
681  pctx->status = amxd_status_duplicate;
682  free(path);
683  goto exit;
684  }
685 
686  amxo_hooks_set_counter(pctx, param_name);
687 
688  retval = true;
689 
690 exit:
691  amxc_string_clean(&res_param_name);
692  return retval;
693 }
694 
696  const char* event,
697  bool event_is_regexp,
698  const char* path,
699  bool path_is_regexp) {
700  int retval = 1;
701  amxc_string_t res_path;
702  amxc_string_t expression;
703  const char* expr = NULL;
704  amxd_dm_t* dm = amxd_object_get_dm(pctx->object);
705  amxp_slot_fn_t fn = (amxp_slot_fn_t) pctx->resolved_fn;
706 
707  amxc_string_init(&expression, 0);
708  amxc_string_init(&res_path, 0);
709 
710  when_true_status(amxo_parser_no_resolve(pctx), exit, retval = 0);
711  when_null(dm, exit);
712 
713  if(pctx->resolved_fn == NULL) {
714  amxo_parser_msg(pctx,
715  "No event subscription created - no function was resolved");
716  pctx->status = amxd_status_ok;
717  goto exit;
718  }
719 
720  if(amxc_string_set_resolved(&res_path, path, &pctx->config) > 0) {
721  path = amxc_string_get(&res_path, 0);
722  }
723  if(path_is_regexp) {
724  amxc_string_appendf(&expression, "object matches \"%s\" || path matches \"%s\"", path, path);
725  } else {
726  amxc_string_appendf(&expression, "object starts with \"%s\" || path starts with \"%s\"", path, path);
727  }
728  expr = amxc_string_get(&expression, 0);
729  retval = amxo_parser_connect(pctx, &dm->sigmngr, event, event_is_regexp, expr, fn);
730 
731 exit:
732  amxc_string_clean(&expression);
733  amxc_string_clean(&res_path);
734 
735  return retval;
736 }
737 
739  const char* event,
740  bool event_is_regexp,
741  const char* full_expr) {
742  int retval = 1;
743  amxd_dm_t* dm = amxd_object_get_dm(pctx->object);
744  amxp_slot_fn_t fn = (amxp_slot_fn_t) pctx->resolved_fn;
745 
746  when_true_status(amxo_parser_no_resolve(pctx), exit, retval = 0);
747  when_null(dm, exit);
748 
749  if(pctx->resolved_fn == NULL) {
750  amxo_parser_msg(pctx,
751  "No event subscription created - no function was resolved");
752  pctx->status = amxd_status_ok;
753  goto exit;
754  }
755 
756  if(full_expr != NULL) {
757  amxc_string_t res_expr;
758  amxc_string_init(&res_expr, 0);
759  if(amxc_string_set_resolved(&res_expr, full_expr, &pctx->config) > 0) {
760  full_expr = amxc_string_get(&res_expr, 0);
761  }
762  retval = amxo_parser_connect(pctx, &dm->sigmngr, event, event_is_regexp, full_expr, fn);
763  amxc_string_clean(&res_expr);
764  } else {
765  retval = amxo_parser_connect(pctx, &dm->sigmngr, event, event_is_regexp, NULL, fn);
766  }
767 
768 exit:
769  return retval;
770 }
771 
773  const char* event,
774  bool event_is_regexp,
775  const char* full_expr) {
776  int retval = 1;
777  amxd_dm_t* dm = amxd_object_get_dm(pctx->object);
778  amxp_slot_fn_t fn = (amxp_slot_fn_t) pctx->resolved_fn;
779  amxc_string_t path_expr;
780 
781  amxc_string_init(&path_expr, 0);
782 
783  when_true_status(amxo_parser_no_resolve(pctx), exit, retval = 0);
784  when_null(dm, exit);
785 
786  if(pctx->resolved_fn == NULL) {
787  amxo_parser_msg(pctx,
788  "No event subscription created - no function was resolved");
789  pctx->status = amxd_status_ok;
790  goto exit;
791  }
792 
793  amxo_parser_build_path_expr(pctx->object, &path_expr);
794  if((full_expr != NULL) && (*full_expr != 0)) {
795  if(amxc_string_is_empty(&path_expr)) {
796  amxc_string_set(&path_expr, full_expr);
797  } else {
798  amxc_string_appendf(&path_expr, " && (%s)", full_expr);
799  }
800  }
801  retval = amxo_parser_connect(pctx,
802  &dm->sigmngr,
803  event,
804  event_is_regexp,
805  amxc_string_get(&path_expr, 0),
806  fn);
807 
808 exit:
809  amxc_string_clean(&path_expr);
810  return retval;
811 }
812 
814  amxo_action_t action,
815  const char* name,
816  amxc_var_t* data) {
817 
818  int retval = -1;
819  bool resolve = !amxo_parser_no_resolve(pctx);
820  pctx->status = amxd_status_ok;
821 
822  if((pctx->sync_contexts != NULL) && amxo_parser_is_sync_item(pctx)) {
823  retval = amxo_parser_set_sync_action(pctx, action, name, data);
824  } else if(pctx->param != NULL) {
825  retval = amxo_parser_set_param_action(pctx, action, name, data);
826  } else {
827  retval = amxo_parser_set_object_action(pctx, action, name, data);
828  }
829 
830  if((pctx->resolved_fn == NULL) && resolve) {
831  retval = 1;
832  pctx->status = amxd_status_file_not_found;
833  amxo_parser_msg(pctx, "Action %d not set - no function resolved", action);
834  }
835 
836  amxc_string_delete(&pctx->resolved_fn_name);
837  if((retval != 0) || !resolve) {
838  amxc_var_delete(&data);
839  }
840  return retval;
841 }
842 
844  const char* mib_name) {
845  bool retval = false;
846  amxd_dm_t* dm = amxd_object_get_dm(pctx->object);
847  amxd_object_t* mib = NULL;
848  amxc_string_t res_mib_name;
849  amxc_string_init(&res_mib_name, 0);
850 
851  if(amxc_string_set_resolved(&res_mib_name, mib_name, &pctx->config) > 0) {
852  mib_name = amxc_string_get(&res_mib_name, 0);
853  }
854 
855  when_null(dm, exit);
856 
857  if(amxd_object_has_mib(pctx->object, mib_name)) {
858  retval = true;
859  goto exit;
860  }
861 
862  mib = amxd_dm_get_mib(dm, mib_name);
863  if(mib == NULL) {
864  const char* file = amxo_parser_get_mib_file(pctx, mib_name);
865  if(file != NULL) {
866  amxo_parser_include(pctx, file);
867  mib = amxd_dm_get_mib(dm, mib_name);
868  }
869  if(mib == NULL) {
870  amxo_parser_msg(pctx, "MIB %s is not found", mib_name);
871  pctx->status = amxd_status_object_not_found;
872  goto exit;
873  }
874  }
875 
876  pctx->status = amxd_object_add_mib(pctx->object, mib_name);
877  if(pctx->status != amxd_status_ok) {
878  amxo_parser_msg(pctx,
879  "Failed to add MIB %s on object %s",
880  mib_name,
881  amxd_object_get_name(pctx->object, AMXD_OBJECT_NAMED));
882  goto exit;
883  }
884 
885  retval = true;
886 
887  amxo_hooks_add_mib(pctx, mib_name);
888 
889 exit:
890  amxc_string_clean(&res_mib_name);
891  return retval;
892 }
static int amxo_parser_set_param_action(amxo_parser_t *pctx, amxo_action_t action, const char *name, amxc_var_t *data)
bool amxo_parser_set_counter(amxo_parser_t *pctx, const char *param_name)
bool amxo_parser_push_object(amxo_parser_t *pctx, const char *path)
int amxo_parser_subscribe_path(amxo_parser_t *pctx, const char *event, bool event_is_regexp, const char *path, bool path_is_regexp)
static int amxo_parser_connect(amxo_parser_t *pctx, amxp_signal_mngr_t *const sig_mngr, const char *const signal_name, bool signal_is_regexp, const char *const expression, amxp_slot_fn_t fn)
static void amxo_parser_push_event(amxo_parser_t *pctx, event_id_t event)
void amxo_parser_free_event(amxc_llist_it_t *it)
static int object_actions[]
static int amxo_parser_can_update_object(amxo_parser_t *pctx, const char *name, amxd_object_type_t type)
static amxd_status_t amxo_parser_set_param_action_impl(amxd_param_t *param, amxd_action_t action, amxd_action_fn_t fn, amxc_var_t *data)
int amxo_parser_subscribe_object(amxo_parser_t *pctx, const char *event, bool event_is_regexp, const char *full_expr)
static amxd_status_t amxo_cleanup_data(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, UNUSED const amxc_var_t *const args, UNUSED amxc_var_t *const retval, void *priv)
int amxo_parser_subscribe(amxo_parser_t *pctx, const char *event, bool event_is_regexp, const char *full_expr)
static int amxo_parser_set_sync_action(amxo_parser_t *pctx, amxo_action_t action, UNUSED const char *name, UNUSED amxc_var_t *data)
int amxo_parser_set_action(amxo_parser_t *pctx, amxo_action_t action, const char *name, amxc_var_t *data)
bool amxo_parser_add_instance(amxo_parser_t *pctx, uint32_t index, const char *name, amxc_var_t *params)
static amxd_object_t * amxd_parser_add_instance_msg(amxo_parser_t *pctx, uint32_t index, const char *name, amxd_object_t *object, amxc_var_t *params)
bool amxo_parser_check_attr(amxo_parser_t *pctx, int64_t attributes, int64_t bitmask)
static int sync_actions[]
bool amxo_parser_pop_object(amxo_parser_t *pctx)
static int64_t amxo_attr_2_object_attr(int64_t attributes)
static amxd_status_t amxo_parser_set_object_action_impl(amxd_object_t *object, amxd_action_t action, amxd_action_fn_t fn, amxc_var_t *data)
static amxd_object_t * amxo_parser_can_update_instance(amxo_parser_t *pctx, uint32_t index, const char *name, amxc_var_t *params)
int amxo_parser_create_object(amxo_parser_t *pctx, const char *name, int64_t attr_bitmask, amxd_object_type_t type)
static void amxo_parser_build_path_expr(amxd_object_t *object, amxc_string_t *expr)
static int amxo_parser_set_object_action(amxo_parser_t *pctx, amxo_action_t action, const char *name, amxc_var_t *data)
static amxd_object_t * amxo_parser_new_object(amxo_parser_t *pctx, amxd_dm_t *dm, const char *name, int64_t oattrs, amxd_object_type_t type)
bool amxo_parser_check_config(amxo_parser_t *pctx, const char *path, const char *check)
static int param_actions[]
bool amxo_parser_set_object_attrs(amxo_parser_t *pctx, uint64_t attr, bool enable)
bool amxo_parser_add_mib(amxo_parser_t *pctx, const char *mib_name)
PRIVATE void amxo_hooks_add_mib(amxo_parser_t *parser, const char *mib)
PRIVATE void amxo_hooks_set_counter(amxo_parser_t *parser, const char *param_name)
PRIVATE void amxo_hooks_select_object(amxo_parser_t *parser, const char *path)
PRIVATE void amxo_hooks_create_object(amxo_parser_t *parser, const char *name, int64_t attr_bitmask, amxd_object_type_t type)
PRIVATE void amxo_hooks_add_instance(amxo_parser_t *parser, uint32_t index, const char *name)
PRIVATE void amxo_hooks_set_action_cb(amxo_parser_t *parser, amxd_object_t *object, amxd_param_t *param, amxd_action_t action_id, const char *action_name, const amxc_var_t *data)
PRIVATE void amxo_hooks_end_object(amxo_parser_t *parser)
@ attr_protected
@ attr_persistent
@ attr_readonly
@ attr_private
PRIVATE amxd_status_t amxo_parser_sync_set_action(amxo_parser_t *pctx, amxs_action_cb_t cb)
PRIVATE amxd_status_t amxo_parser_sync_set_translator(amxo_parser_t *pctx, amxs_translation_cb_t cb)
@ action_translate
@ action_apply
PRIVATE bool amxo_parser_no_resolve(amxo_parser_t *parser)
PRIVATE void amxo_parser_msg(amxo_parser_t *parser, const char *format,...) __attribute__((format(printf
PRIVATE int amxo_parser_include(amxo_parser_t *pctx, const char *file_path)
enum _amxo_action amxo_action_t
PRIVATE bool amxo_parser_is_sync_item(amxo_parser_t *pctx)
enum _event_id event_id_t
@ event_instance_add
@ event_object_change
@ event_none
const char * amxo_parser_get_mib_file(amxo_parser_t *parser, const char *mib_name)
Get full path and file name of odl file describing a mib.
The ODL parser structure.
Definition: amxo_types.h:245
amxo_fn_ptr_t resolved_fn
Definition: amxo_types.h:266
amxc_astack_t object_stack
Definition: amxo_types.h:261
amxc_lstack_t event_list
Definition: amxo_types.h:283
amxc_llist_t function_names
Definition: amxo_types.h:268
amxd_param_t * param
Definition: amxo_types.h:263
amxc_var_t config
Definition: amxo_types.h:250
amxc_string_t * resolved_fn_name
Definition: amxo_types.h:267
amxd_status_t status
Definition: amxo_types.h:258
amxd_object_t * object
Definition: amxo_types.h:262
amxc_llist_t * sync_contexts
Definition: amxo_types.h:290
char * path
event_id_t id
amxc_llist_it_t it
amxc_var_t data
#define UNUSED
Definition: test_issue_48.c:84