libamxd  6.4.1
Data Model Manager
amxd_object_instance.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_types.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_object_expression.h>
#include <amxd/amxd_action.h>
#include <amxd/amxd_dm.h>
#include "amxd_priv.h"
#include "amxd_dm_priv.h"
#include "amxd_object_priv.h"
#include "amxd_assert.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static bool amxd_template_has_instance (const amxd_object_t *const templ, const char *name)
 
static bool amxd_template_has_index (const amxd_object_t *const templ, uint32_t index)
 
static amxd_status_t amxd_object_check_instance_alias (amxd_object_t *const templ, amxc_var_t *templ_params, amxc_htable_t *values, uint32_t index, const char **name)
 
static amxd_status_t amxd_object_instance_validate_id (amxd_object_t *templ, const char **name, uint32_t index, amxc_var_t *templ_params, amxc_var_t *values)
 
static amxd_status_t amxd_object_instance_set_index_name (amxd_object_t *object, amxd_object_t *templ, const char *name, uint32_t index)
 
static amxd_status_t amxd_object_instantiate (amxd_object_t **object, amxd_object_t *templ, const char *name, uint32_t index, amxc_var_t *templ_params, amxc_var_t *tmp_values)
 
static amxd_status_t amxd_cleanup_max_instance (amxd_object_t *const object, UNUSED amxd_param_t *const param, amxd_action_t reason, UNUSED const amxc_var_t *const args, UNUSED amxc_var_t *const retval, void *priv)
 
static void amxd_object_remove_max_instance_check (amxd_object_t *object, amxc_var_t *max_var)
 
static amxd_status_t amxd_object_add_max_instance_check (amxd_object_t *object, uint32_t max)
 
amxd_status_t amxd_object_new_instance (amxd_object_t **object, amxd_object_t *templ, const char *name, uint32_t index, amxc_var_t *values)
 Data model object constructor function. More...
 
amxd_status_t amxd_object_set_max_instances (amxd_object_t *object, uint32_t max)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxd_object_instance.c.

Function Documentation

◆ amxd_cleanup_max_instance()

static amxd_status_t amxd_cleanup_max_instance ( amxd_object_t *const  object,
UNUSED amxd_param_t *const  param,
amxd_action_t  reason,
UNUSED const amxc_var_t *const  args,
UNUSED amxc_var_t *const  retval,
void *  priv 
)
static

Definition at line 286 of file amxd_object_instance.c.

291  {
293  amxc_var_t* data = (amxc_var_t*) priv;
294 
295  // action private data must not be removed when the action is used
296  // on derivced objects.
297  // only remove action data when the action is owned by the object or
298  // parameter on which the action is called.
300  amxc_var_delete(&data);
302  }
303 
304  return status;
305 }
bool amxd_object_has_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
void amxd_object_set_action_cb_data(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn, void *data)
static amxd_status_t amxd_cleanup_max_instance(amxd_object_t *const object, UNUSED amxd_param_t *const param, amxd_action_t reason, UNUSED const amxc_var_t *const args, UNUSED amxc_var_t *const retval, void *priv)
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78
static amxd_status_t status

◆ amxd_object_add_max_instance_check()

static amxd_status_t amxd_object_add_max_instance_check ( amxd_object_t object,
uint32_t  max 
)
static

Definition at line 320 of file amxd_object_instance.c.

321  {
322  amxc_var_t* max_var = NULL;
324 
325  amxc_var_new(&max_var);
326  amxc_var_set(uint32_t, max_var, max);
327  retval = amxd_object_add_action_cb(object,
330  max_var);
331  when_failed_status(retval, exit, amxc_var_delete(&max_var));
332  retval = amxd_object_add_action_cb(object,
335  max_var);
336  if(retval != amxd_status_ok) {
340  amxc_var_delete(&max_var);
341  goto exit;
342  }
343 
344  retval = amxd_status_ok;
345 
346 exit:
347  return retval;
348 }
amxd_status_t amxd_action_object_add_inst(amxd_object_t *const object, amxd_param_t *const param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
#define when_failed_status(x, l, c)
Definition: amxd_assert.h:65
amxd_status_t amxd_object_add_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn, void *priv)
amxd_status_t amxd_object_remove_action_cb(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
@ action_object_add_inst
Definition: amxd_types.h:123
@ action_object_destroy
Definition: amxd_types.h:125
@ amxd_status_unknown_error
Definition: amxd_types.h:79

◆ amxd_object_check_instance_alias()

static amxd_status_t amxd_object_check_instance_alias ( amxd_object_t *const  templ,
amxc_var_t *  templ_params,
amxc_htable_t *  values,
uint32_t  index,
const char **  name 
)
static

Definition at line 115 of file amxd_object_instance.c.

119  {
121  amxc_var_t* alias = amxc_var_get_key(templ_params, "Alias", AMXC_VAR_FLAG_DEFAULT);
122  amxc_htable_it_t* halias = amxc_htable_get(values, "Alias");
123  const char* obj_name = amxd_object_get_name(templ, AMXD_OBJECT_NAMED);
124  uint32_t new_index = index == 0 ? (templ->last_index + 1) : index;
125  amxc_var_t* alias_var = NULL;
126 
127  when_null(alias, exit);
128  when_true(!amxc_var_constcast(bool, GET_FIELD(alias, "attributes.key")), exit);
129  when_true(!amxc_var_constcast(bool, GET_FIELD(alias, "attributes.unique")), exit);
130 
131  if(halias == NULL) {
132  amxc_var_new(&alias_var);
133  if((*name != NULL) && ((*name)[0] != 0)) {
134  amxc_var_set(cstring_t, alias_var, *name);
135  } else {
136  amxc_string_t alias_name;
137  amxc_string_init(&alias_name, 0);
138  amxc_string_appendf(&alias_name, "cpe-%s-%d", obj_name, new_index);
139  amxc_var_push(amxc_string_t, alias_var, &alias_name);
140  amxc_string_clean(&alias_name);
141  }
142  amxc_htable_insert(values, "Alias", &alias_var->hit);
143  } else {
144  alias_var = amxc_var_from_htable_it(halias);
145  if((amxc_var_type_of(alias_var) != AMXC_VAR_ID_CSTRING) &&
146  ( amxc_var_type_of(alias_var) != AMXC_VAR_ID_SSV_STRING) &&
147  ( amxc_var_type_of(alias_var) != AMXC_VAR_ID_CSV_STRING)) {
149  goto exit;
150  }
151  }
152 
153  *name = amxc_var_constcast(cstring_t, alias_var);
154  if(isdigit((*name)[0]) != 0) {
156  }
157  *name = "";
158 
159 exit:
160  return status;
161 }
#define GET_FIELD(var, field)
Definition: amxd_priv.h:76
@ amxd_status_invalid_name
Definition: amxd_types.h:86
@ amxd_status_invalid_value
Definition: amxd_types.h:88
#define AMXD_OBJECT_NAMED
Name and path format flag - default behavior, use name for instance objects.
Definition: amxd_object.h:164
const char * amxd_object_get_name(const amxd_object_t *const object, const uint32_t flags)
Get the name of the object (or index as a string for instance objects)
Definition: amxd_object.c:239
uint32_t last_index
Definition: amxd_types.h:241

◆ amxd_object_instance_set_index_name()

static amxd_status_t amxd_object_instance_set_index_name ( amxd_object_t object,
amxd_object_t templ,
const char *  name,
uint32_t  index 
)
static

Definition at line 203 of file amxd_object_instance.c.

206  {
208  uint32_t index_try = 0;
209  int size_needed = 0;
210 
211  if(index == 0) {
212  while(amxd_template_has_index(templ, templ->last_index + 1)) {
213  index_try++;
214  templ->last_index++;
215 
216  if(index_try > 10) {
217  goto exit;
218  }
219  }
220  object->index = templ->last_index + 1;
221  } else {
222  object->index = index;
223  }
224 
225  size_needed = snprintf(NULL, 0, "%" PRIu32, object->index);
226  object->index_name = (char*) calloc(size_needed + 1, sizeof(char));
227  when_null(object->index_name, exit);
228  snprintf(object->index_name, size_needed + 1, "%" PRIu32, object->index);
229  if(object->name == NULL) {
230  if((name == NULL) || (name[0] == 0)) {
231  object->name = strdup(object->index_name);
232  when_null(object->name, exit);
233  }
234  }
235  if(object->index > templ->last_index) {
236  templ->last_index = object->index;
237  }
238 
239  retval = amxd_status_ok;
240 
241 exit:
242  return retval;
243 }
static bool amxd_template_has_index(const amxd_object_t *const templ, uint32_t index)
uint32_t index
Definition: amxd_types.h:240
char * name
Definition: amxd_types.h:238
char * index_name
Definition: amxd_types.h:239

◆ amxd_object_instance_validate_id()

static amxd_status_t amxd_object_instance_validate_id ( amxd_object_t templ,
const char **  name,
uint32_t  index,
amxc_var_t *  templ_params,
amxc_var_t *  values 
)
static

Definition at line 163 of file amxd_object_instance.c.

167  {
168  amxd_status_t retval = amxd_status_ok;
169  amxp_expr_t* expr = NULL;
170  amxc_htable_t* hvalues = (amxc_htable_t*) amxc_var_constcast(amxc_htable_t, values);
171  bool has_matches = false;
172 
173  if(index != 0) {
174  when_true_status(amxd_template_has_index(templ, index),
175  exit,
176  retval = amxd_status_duplicate);
177  }
178 
179  retval = amxd_object_check_instance_alias(templ, templ_params, hvalues, index, name);
180  when_true(retval != amxd_status_ok, exit);
181 
182  retval = amxd_object_build_key_expr(templ_params, &expr, hvalues);
183  when_failed(retval, exit);
184 
185  has_matches = amxd_object_has_matching_instances(templ, expr);
186  when_true_status(has_matches, exit, retval = amxd_status_duplicate);
187 
188 
189  if((*name != NULL) && ((*name)[0] != 0)) {
190  when_true_status(!amxd_name_is_valid(*name),
191  exit,
192  retval = amxd_status_invalid_name);
193  when_true_status(amxd_template_has_instance(templ, *name),
194  exit,
195  retval = amxd_status_duplicate);
196  }
197 
198 exit:
199  amxp_expr_delete(&expr);
200  return retval;
201 }
bool amxd_name_is_valid(const char *name)
Definition: amxd_common.c:115
bool amxd_object_has_matching_instances(const amxd_object_t *const templ, amxp_expr_t *expr)
static bool amxd_template_has_instance(const amxd_object_t *const templ, const char *name)
static amxd_status_t amxd_object_check_instance_alias(amxd_object_t *const templ, amxc_var_t *templ_params, amxc_htable_t *values, uint32_t index, const char **name)
PRIVATE amxd_status_t amxd_object_build_key_expr(amxc_var_t *const templ_params, amxp_expr_t **expr, const amxc_htable_t *const data)
@ amxd_status_duplicate
Definition: amxd_types.h:91

◆ amxd_object_instantiate()

static amxd_status_t amxd_object_instantiate ( amxd_object_t **  object,
amxd_object_t templ,
const char *  name,
uint32_t  index,
amxc_var_t *  templ_params,
amxc_var_t *  tmp_values 
)
static

Definition at line 245 of file amxd_object_instance.c.

250  {
252  uint32_t attrs = 0;
253  amxd_param_t* counter = NULL;
254 
255  *object = (amxd_object_t*) calloc(1, sizeof(amxd_object_t));
256  when_null((*object), exit);
257  retval = amxd_object_init(*object, amxd_object_instance, name, templ_params, tmp_values);
258  when_true(retval != amxd_status_ok, exit);
259  retval = amxd_object_instance_set_index_name((*object), templ, name, index);
260  when_true(retval != amxd_status_ok, exit);
261  attrs = amxd_object_get_attrs(templ);
262  amxd_object_set_attrs(*object, attrs, true);
263 
264  amxc_llist_append(&templ->instances, &(*object)->it);
265  retval = amxd_object_copy_children((*object), templ);
266  when_failed(retval, exit);
267  retval = amxd_object_copy_params((*object), templ);
268  when_failed(retval, exit);
269  retval = amxd_object_copy_mib_names((*object), templ);
270 
272  when_null(counter, exit);
274 
275 exit:
276  if(*object != NULL) {
277  if(retval != amxd_status_ok) {
278  amxd_object_clean(*object);
279  free(*object);
280  *object = NULL;
281  }
282  }
283  return retval;
284 }
static amxd_status_t amxd_object_instance_set_index_name(amxd_object_t *object, amxd_object_t *templ, const char *name, uint32_t index)
amxd_param_t * amxd_object_get_param_counter_by_counted_object(const amxd_object_t *const object)
Gets a parameter definition associated with a counted object.
PRIVATE void amxd_object_clean(amxd_object_t *const object)
PRIVATE amxd_status_t amxd_object_copy_params(amxd_object_t *const dst, const amxd_object_t *const src)
PRIVATE amxd_status_t amxd_object_copy_children(amxd_object_t *const dst, const amxd_object_t *const src)
PRIVATE amxd_status_t amxd_object_init(amxd_object_t *const object, const amxd_object_type_t type, const char *name, amxc_var_t *templ_params, amxc_var_t *values)
PRIVATE amxd_status_t amxd_object_copy_mib_names(amxd_object_t *const dst, const amxd_object_t *const src)
amxd_status_t amxd_param_counter_update(amxd_param_t *counter)
@ amxd_object_instance
Definition: amxd_types.h:186
amxd_status_t amxd_object_set_attrs(amxd_object_t *const object, const uint32_t bitmask, bool enable)
Sets or unsets object attributes using a bitmap.
Definition: amxd_object.c:301
uint32_t amxd_object_get_attrs(const amxd_object_t *const object)
Gets the set attributes of an object.
Definition: amxd_object.c:334
amxc_llist_t instances
Definition: amxd_types.h:244
static int counter

◆ amxd_object_remove_max_instance_check()

static void amxd_object_remove_max_instance_check ( amxd_object_t object,
amxc_var_t *  max_var 
)
static

Definition at line 307 of file amxd_object_instance.c.

308  {
309  if(max_var != NULL) {
310  amxc_var_delete(&max_var);
317  }
318 }

◆ amxd_object_set_max_instances()

amxd_status_t amxd_object_set_max_instances ( amxd_object_t object,
uint32_t  max 
)

Definition at line 397 of file amxd_object_instance.c.

398  {
400  amxc_var_t* max_var = NULL;
401  uint32_t instances = 0;
402  when_null(object, exit);
403  when_true_status(object->type != amxd_object_template,
404  exit,
405  retval = amxd_status_invalid_type);
406 
407  instances = amxd_object_get_instance_count(object);
408  when_true_status(max < instances, exit, retval = amxd_status_invalid_value);
409 
410  max_var =
411  (amxc_var_t*) amxd_object_get_action_cb_data(object,
414  if(max == UINT32_MAX) {
415  amxd_object_remove_max_instance_check(object, max_var);
416  retval = amxd_status_ok;
417  goto exit;
418  }
419 
420  if(max_var != NULL) {
421  amxc_var_set(uint32_t, max_var, max);
422  } else {
423  retval = amxd_object_add_max_instance_check(object, max);
424  when_failed(retval, exit);
425  }
426 
427  retval = amxd_status_ok;
428 
429 exit:
430  return retval;
431 }
void * amxd_object_get_action_cb_data(amxd_object_t *const object, const amxd_action_t reason, amxd_action_fn_t fn)
static uint32_t amxd_object_get_instance_count(const amxd_object_t *object)
static void amxd_object_remove_max_instance_check(amxd_object_t *object, amxc_var_t *max_var)
static amxd_status_t amxd_object_add_max_instance_check(amxd_object_t *object, uint32_t max)
@ amxd_status_invalid_type
Definition: amxd_types.h:90
@ amxd_object_template
Definition: amxd_types.h:183
amxd_object_type_t type
Definition: amxd_types.h:236

◆ amxd_template_has_index()

static bool amxd_template_has_index ( const amxd_object_t *const  templ,
uint32_t  index 
)
static

Definition at line 95 of file amxd_object_instance.c.

96  {
97  bool retval = false;
98 
99  if(index != 0) {
100  amxc_llist_for_each(it, (&templ->instances)) {
101  amxd_object_t* result = amxc_llist_it_get_data(it, amxd_object_t, it);
102  if(result->index == index) {
103  retval = true;
104  break;
105  }
106  }
107  } else {
108  // index 0 is a special case, it can not be used as an index id
109  // it is considered always available.
110  retval = true;
111  }
112  return retval;
113 }

◆ amxd_template_has_instance()

static bool amxd_template_has_instance ( const amxd_object_t *const  templ,
const char *  name 
)
static

Definition at line 78 of file amxd_object_instance.c.

79  {
80  bool retval = false;
81 
82  amxc_llist_for_each(it, (&templ->instances)) {
83  const char* n = NULL;
84  amxd_object_t* result = amxc_llist_it_get_data(it, amxd_object_t, it);
86  if(strcmp(n, name) == 0) {
87  retval = true;
88  break;
89  }
90  }
91 
92  return retval;
93 }