61 #define PARAM_ATTR(param, attr_name) \
62 amxc_var_dyncast(bool, \
63 amxc_var_get_path(param, \
65 AMXC_VAR_FLAG_DEFAULT))
67 #define PARAM_NAME(param) \
68 amxc_var_constcast(cstring_t, \
69 amxc_var_get_path(param, \
71 AMXC_VAR_FLAG_DEFAULT))
73 #define PARAM_FLAGS(param) \
74 amxc_var_constcast(amxc_llist_t, \
75 amxc_var_get_path(param, \
77 AMXC_VAR_FLAG_DEFAULT))
79 #define PARAM_VALUE(param) \
80 amxc_var_get_path(param, \
82 AMXC_VAR_FLAG_DEFAULT)
88 amxd_object_t*
object,
90 amxc_string_t* buffer);
94 amxc_string_t* buffer,
95 const char* termination);
101 while(length != bytes) {
102 written =
write(fd, buf + length, bytes - length);
114 static const char* spaces =
"\t\t\t\t\t\t\t\t\t\t";
123 const char* buf = amxc_string_get(buffer, 0);
124 size_t length = amxc_string_text_length(buffer);
128 amxc_string_reset(buffer);
133 amxc_string_t* buffer,
139 amxc_string_vappendf(buffer, fmt, args);
142 if(amxc_string_text_length(buffer) >
buffer_size) {
148 const char* filename,
150 char* full_name = NULL;
151 amxc_string_t full_path;
153 amxc_string_init(&full_path, 128);
154 amxc_string_appendf(&full_path,
"%s%s", filename, temp ?
".tmp" :
"");
155 amxc_string_resolve(&full_path, &pctx->
config);
156 full_name = amxc_string_take_buffer(&full_path);
157 amxc_string_clean(&full_path);
168 length = read(source_fd, buffer, 1024);
171 when_failed(retval, exit);
172 length = read(source_fd, buffer, 1024);
180 const char* filename,
185 char* real_path = NULL;
186 int open_flags = O_CREAT | O_WRONLY | O_TRUNC;
187 int mode_flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
190 real_path = realpath(full_path, NULL);
191 when_null(real_path, exit);
193 fd = open(full_path_tmp, open_flags, mode_flags);
194 when_true(fd == -1, exit);
197 int orig_fd = open(real_path, O_RDONLY);
221 amxc_string_t* buffer) {
223 const char* sep =
",";
226 amxc_var_for_each(val, value) {
227 const char* key = amxc_var_key(val);
228 if(amxc_var_get_next(val) == NULL) {
232 if(strchr(key,
'.') != NULL) {
239 when_true(retval < 0, exit);
249 amxc_string_t* buffer) {
251 const char* sep =
",";
253 amxc_var_for_each(val, value) {
254 if(amxc_var_get_next(val) == NULL) {
260 when_true(retval < 0, exit);
269 amxc_string_esc(value);
274 amxc_string_t* buffer,
275 const char* termination) {
276 int type = amxc_var_type_of(value);
280 case AMXC_VAR_ID_INT8:
281 case AMXC_VAR_ID_INT16:
282 case AMXC_VAR_ID_INT32:
283 case AMXC_VAR_ID_INT64:
284 case AMXC_VAR_ID_UINT8:
285 case AMXC_VAR_ID_UINT16:
286 case AMXC_VAR_ID_UINT32:
287 case AMXC_VAR_ID_UINT64:
288 case AMXC_VAR_ID_BOOL:
289 txt = amxc_var_dyncast(cstring_t, value);
293 case AMXC_VAR_ID_TIMESTAMP:
294 txt = amxc_var_dyncast(cstring_t, value);
298 case AMXC_VAR_ID_CSTRING:
299 case AMXC_VAR_ID_SSV_STRING:
300 case AMXC_VAR_ID_CSV_STRING: {
301 amxc_string_t str_value;
302 amxc_string_init(&str_value, 0);
303 amxc_string_set(&str_value, amxc_var_constcast(cstring_t, value));
305 amxo_parser_writef(fd, buffer,
"\"%s\"%s", amxc_string_get(&str_value, 0), termination);
306 amxc_string_clean(&str_value);
309 case AMXC_VAR_ID_HTABLE:
316 case AMXC_VAR_ID_LIST:
334 amxc_string_t* buffer) {
338 amxc_var_for_each(val,
config) {
339 const char* key = amxc_var_key(val);
341 if(strchr(key,
'.') != NULL) {
348 when_true(retval < 0, exit);
359 amxc_llist_for_each(it, flags) {
360 amxc_var_t* flag = amxc_var_from_llist_it(it);
361 if(strcmp(GET_CHAR(flag, NULL),
"odl-creation-param") == 0) {
373 amxc_htable_for_each(it, params) {
374 amxc_var_t* param = amxc_var_from_htable_it(it);
375 const amxc_llist_t* flags = amxc_var_constcast(amxc_llist_t,
376 GET_ARG(param,
"flags"));
393 amxd_object_t*
object,
394 amxc_string_t* buffer) {
396 const amxc_htable_t* ht_params = NULL;
398 const char* inst_name = amxd_object_get_name(
object, AMXD_OBJECT_NAMED);
402 if(amxd_name_is_valid(inst_name)) {
406 amxc_var_init(¶ms);
407 amxd_object_describe_params(
object, ¶ms, amxd_dm_access_public);
408 ht_params = amxc_var_constcast(amxc_htable_t, ¶ms);
410 amxc_htable_for_each(it, ht_params) {
411 amxc_var_t* param = amxc_var_from_htable_it(it);
412 const char* name = amxc_htable_it_get_key(it);
414 bool is_key_param =
PARAM_ATTR(param,
"attributes.key");
416 if(!is_key_param && !is_creation_param) {
421 when_true(retval < 0, exit);
427 amxc_var_clean(¶ms);
432 amxd_object_t*
object,
433 amxc_string_t* buffer) {
435 if(amxd_object_get_type(
object) != amxd_object_root) {
437 amxd_object_get_parent(
object),
439 when_true(retval < 0, exit);
442 if(amxd_object_get_type(
object) == amxd_object_root) {
446 if(amxd_object_get_type(
object) == amxd_object_instance) {
452 amxd_object_get_name(
object, AMXD_OBJECT_NAMED));
461 amxd_object_t*
object,
462 amxc_string_t* buffer) {
464 amxc_array_it_t* it = amxc_array_get_first(&object->mib_names);
466 const char* name = (
const char*) amxc_array_it_get_data(it);
469 it = amxc_array_it_get_next(it);
477 amxc_string_t* buffer) {
480 const char* sep =
"";
485 amxc_llist_iterate(it, flags) {
486 amxc_var_t* var_flag = amxc_var_from_llist_it(it);
487 const char* flag = amxc_var_constcast(cstring_t, var_flag);
500 amxc_var_t* attrs = GET_ARG(param,
"attributes");
501 bool is_templ_param = GET_BOOL(attrs,
"template");
502 bool is_inst_param = GET_BOOL(attrs,
"instance");
503 bool is_key_param = GET_BOOL(attrs,
"key");
504 bool is_persist_param = GET_BOOL(attrs,
"persistent");
506 bool must_save =
true;
508 if(amxd_object_get_type(
object) == amxd_object_template) {
509 if(is_key_param || is_creation_param ||
510 !is_persist_param || !is_templ_param) {
513 }
else if(amxd_object_get_type(
object) == amxd_object_instance) {
514 if(is_key_param || is_creation_param ||
515 !is_persist_param || !is_inst_param) {
519 if(!is_persist_param) {
528 amxd_object_t*
object,
529 amxc_string_t* buffer) {
531 const amxc_htable_t* ht_params = NULL;
533 amxc_var_init(¶ms);
535 amxd_object_describe_params(
object, ¶ms, amxd_dm_access_private);
536 ht_params = amxc_var_constcast(amxc_htable_t, ¶ms);
538 amxc_htable_for_each(it, ht_params) {
539 amxc_var_t* param = amxc_var_from_htable_it(it);
551 when_true(retval < 0, exit);
552 if(!amxc_llist_is_empty(flags)) {
560 amxc_var_clean(¶ms);
567 amxc_string_t* buffer) {
569 amxd_object_t* obj = amxc_container_of(it, amxd_object_t, it);
570 if(!amxd_object_is_attr_set(obj, amxd_oattr_persistent) &&
571 ( amxd_object_get_type(obj) != amxd_object_template)) {
574 if(amxd_object_get_type(obj) == amxd_object_instance) {
580 amxd_object_get_name(obj, AMXD_OBJECT_NAMED));
585 when_true(retval < 0, exit);
595 amxd_object_t*
object,
597 amxc_string_t* buffer) {
600 if(amxd_object_get_type(
object) != amxd_object_root) {
602 when_failed(retval, exit);
604 when_failed(retval, exit);
605 if(depth != UINT32_MAX) {
609 when_true(depth == 0, exit);
612 if(amxd_object_get_type(
object) == amxd_object_template) {
613 amxd_object_for_each(instance, it,
object) {
615 when_failed(retval, exit);
618 amxd_object_for_each(child, it,
object) {
620 when_failed(retval, exit);
629 amxd_object_t*
object,
630 amxc_string_t* buffer) {
632 if(amxd_object_get_type(
object) == amxd_object_root) {
641 amxd_object_get_parent(
object),
649 amxd_object_t*
object,
651 amxc_string_t* buffer) {
657 when_failed(retval, exit);
659 when_failed(retval, exit);
661 when_failed(retval, exit);
671 const char* filename,
676 unlink(full_path_tmp);
681 const char* filename,
688 when_failed(retval, exit);
690 when_failed(retval, exit);
691 retval = rename(full_path_tmp, full_path);
692 when_failed(retval, exit);
701 const char* filename,
702 amxd_object_t*
object,
708 amxc_string_t buffer;
710 if(GETP_ARG(&pctx->
config,
"odl.buffer-size") != NULL) {
715 when_null(pctx, exit);
716 when_str_empty(filename, exit);
719 pctx->
status = amxd_status_ok;
721 when_true(fd < 0, exit);
722 if((
config != NULL) && (amxc_var_type_of(
config) == AMXC_VAR_ID_HTABLE)) {
724 when_true(retval < 0, exit);
729 when_true(retval < 0, exit);
744 amxc_string_clean(&buffer);
749 const char* filename,
756 const char* filename,
757 amxd_object_t*
object,
#define PARAM_FLAGS(param)
static int amxo_parser_save_config_options(int fd, amxc_var_t *config, amxc_string_t *buffer)
#define PARAM_NAME(param)
static int amxo_parser_save_value(int fd, amxc_var_t *value, amxc_string_t *buffer, const char *termination)
static char * amxo_parser_build_filename(amxo_parser_t *pctx, const char *filename, bool temp)
#define PARAM_ATTR(param, attr_name)
static void amxo_parser_indent(amxc_string_t *buffer)
static void amxo_parser_escape_value(amxc_string_t *value)
static int amxo_parser_flush_buffer(int fd, amxc_string_t *buffer)
static int amxo_parser_save_list_config(int fd, amxc_var_t *value, amxc_string_t *buffer)
static int amxo_parser_copy(int dest_fd, int source_fd)
static int amxo_parser_instance_header(int fd, amxd_object_t *object, amxc_string_t *buffer)
static void amxo_parser_writef(int fd, amxc_string_t *buffer, const char *fmt,...)
static bool amxo_parser_must_save_param(amxd_object_t *object, amxc_var_t *param)
static int amxo_parser_save_tree(int fd, amxd_object_t *object, uint32_t depth, amxc_string_t *buffer)
static int amxo_parser_write(int fd, const char *buf, size_t bytes)
static int amxo_parser_save_leave(int fd, amxc_llist_it_t *it, uint32_t depth, amxc_string_t *buffer)
static int amxo_parser_open_file(amxo_parser_t *pctx, const char *filename, bool append)
static size_t buffer_size
static int amxo_parser_save_param_flags(int fd, amxc_var_t *param, amxc_string_t *buffer)
int amxo_parser_save_object(amxo_parser_t *pctx, const char *filename, amxd_object_t *object, bool append)
static int amxo_parser_close_file(amxo_parser_t *pctx, const char *filename, int fd)
static void amxo_parser_remove_file(amxo_parser_t *pctx, const char *filename, int fd)
#define PARAM_VALUE(param)
int amxo_parser_save_config(amxo_parser_t *pctx, const char *filename, amxc_var_t *config, bool append)
static bool amxo_parser_is_creation_parameter(const amxc_llist_t *flags)
int amxo_parser_save(amxo_parser_t *pctx, const char *filename, amxd_object_t *object, uint32_t depth, amxc_var_t *config, bool append)
static int amxo_parser_save_table_config(int fd, amxc_var_t *value, amxc_string_t *buffer)
static bool amxo_parser_has_key_params(const amxc_htable_t *params)
static int amxo_parser_open_parent_tree(int fd, amxd_object_t *object, amxc_string_t *buffer)
static int amxo_parser_save_mibs(int fd, amxd_object_t *object, amxc_string_t *buffer)
static int amxo_parser_close_parent_tree(int fd, amxd_object_t *object, amxc_string_t *buffer)
static int amxo_parser_save_object_tree(int fd, amxd_object_t *object, uint32_t depth, amxc_string_t *buffer)
static int amxo_parser_save_params(int fd, amxd_object_t *object, amxc_string_t *buffer)
The ODL parser structure.