diff --git a/src/core/cfg/cfg_ctx.c b/src/core/cfg/cfg_ctx.c index 87ccda81c43..4c079969505 100644 --- a/src/core/cfg/cfg_ctx.c +++ b/src/core/cfg/cfg_ctx.c @@ -1359,6 +1359,74 @@ int cfg_get_by_name(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str return 0; } +/* retrieves the default value of a variable + * Return value: + * 0 - success + * -1 - error + * 1 - variable exists, but it is not readable + */ +int cfg_get_default_value_by_name(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str *var_name, + void **val, unsigned int *val_type) +{ + cfg_group_t *group; + cfg_mapping_t *var; + void *p; + static str s; /* we need the value even + after the function returns */ + cfg_group_inst_t *group_inst; + + /* verify the context even if we do not need it now + to make sure that a cfg driver has called the function + (very very weak security) */ + if (!ctx) { + LOG(L_ERR, "ERROR: cfg_get_by_name(): context is undefined\n"); + return -1; + } + + /* look-up the group and the variable */ + if (cfg_lookup_var(group_name, var_name, &group, &var)) + return -1; + else + { + if(var->def->type & CFG_READONLY) /* if variables exist then prevents resetting the read-only ones */ + return -1; + } + + if (var->def->on_change_cb) { + /* The variable cannot be retrieved, because the fixup + function may have changed it, and it is better to return + an error than an incorrect value */ + return 1; + } + + /* use the module's orig_handle to access the default registered value of the variable for any group*/ + p = (group->orig_handle) + var->offset; + + switch (CFG_VAR_TYPE(var)) { + case CFG_VAR_INT: + *val = (void *)(long)*(int *)p; + break; + + case CFG_VAR_STRING: + *val = (void *)*(char **)p; + break; + + case CFG_VAR_STR: + memcpy(&s, p, sizeof(str)); + *val = (void *)&s; + break; + + case CFG_VAR_POINTER: + *val = *(void **)p; + break; + + } + *val_type = CFG_VAR_TYPE(var); + + return 0; +} + + /* returns the description of a variable */ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name, char **ch, unsigned int *input_type) diff --git a/src/core/cfg/cfg_ctx.h b/src/core/cfg/cfg_ctx.h index 9401daed774..2ecae7deaf3 100644 --- a/src/core/cfg/cfg_ctx.h +++ b/src/core/cfg/cfg_ctx.h @@ -119,6 +119,9 @@ int cfg_rollback(cfg_ctx_t *ctx); int cfg_get_by_name(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str *var_name, void **val, unsigned int *val_type); +int cfg_get_default_value_by_name(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str *var_name, + void **val, unsigned int *val_type); + /*! \brief returns the description of a variable */ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name, char **ch, unsigned int *input_type); diff --git a/src/modules/cfg_rpc/README b/src/modules/cfg_rpc/README index d0315431b6e..93d31e0a0c6 100644 --- a/src/modules/cfg_rpc/README +++ b/src/modules/cfg_rpc/README @@ -24,19 +24,20 @@ Miklos Tirpak 3.3. cfg.seti 3.4. cfg.set_now_int 3.5. cfg.sets - 3.6. cfg.set_now_string - 3.7. cfg.set - 3.8. cfg.del - 3.9. cfg.set_delayed_int - 3.10. cfg.set_delayed_string - 3.11. cfg.set_delayed - 3.12. cfg.del_delayed - 3.13. cfg.commit - 3.14. cfg.rollback - 3.15. cfg.help - 3.16. cfg.diff - 3.17. cfg.add_group_inst - 3.18. cfg.del_group_inst + 3.6. cfg.reset + 3.7. cfg.set_now_string + 3.8. cfg.set + 3.9. cfg.del + 3.10. cfg.set_delayed_int + 3.11. cfg.set_delayed_string + 3.12. cfg.set_delayed + 3.13. cfg.del_delayed + 3.14. cfg.commit + 3.15. cfg.rollback + 3.16. cfg.help + 3.17. cfg.diff + 3.18. cfg.add_group_inst + 3.19. cfg.del_group_inst List of Examples @@ -44,6 +45,7 @@ Miklos Tirpak 1.2. Use cfg.get RPC command 1.3. Use cfg.seti RPC command 1.4. Use cfg.sets RPC command + 1.5. Use cfg.reset RPC command Chapter 1. Admin Guide @@ -62,19 +64,20 @@ Chapter 1. Admin Guide 3.3. cfg.seti 3.4. cfg.set_now_int 3.5. cfg.sets - 3.6. cfg.set_now_string - 3.7. cfg.set - 3.8. cfg.del - 3.9. cfg.set_delayed_int - 3.10. cfg.set_delayed_string - 3.11. cfg.set_delayed - 3.12. cfg.del_delayed - 3.13. cfg.commit - 3.14. cfg.rollback - 3.15. cfg.help - 3.16. cfg.diff - 3.17. cfg.add_group_inst - 3.18. cfg.del_group_inst + 3.6. cfg.reset + 3.7. cfg.set_now_string + 3.8. cfg.set + 3.9. cfg.del + 3.10. cfg.set_delayed_int + 3.11. cfg.set_delayed_string + 3.12. cfg.set_delayed + 3.13. cfg.del_delayed + 3.14. cfg.commit + 3.15. cfg.rollback + 3.16. cfg.help + 3.17. cfg.diff + 3.18. cfg.add_group_inst + 3.19. cfg.del_group_inst 1. Overview @@ -114,19 +117,20 @@ Chapter 1. Admin Guide 3.3. cfg.seti 3.4. cfg.set_now_int 3.5. cfg.sets - 3.6. cfg.set_now_string - 3.7. cfg.set - 3.8. cfg.del - 3.9. cfg.set_delayed_int - 3.10. cfg.set_delayed_string - 3.11. cfg.set_delayed - 3.12. cfg.del_delayed - 3.13. cfg.commit - 3.14. cfg.rollback - 3.15. cfg.help - 3.16. cfg.diff - 3.17. cfg.add_group_inst - 3.18. cfg.del_group_inst + 3.6. cfg.reset + 3.7. cfg.set_now_string + 3.8. cfg.set + 3.9. cfg.del + 3.10. cfg.set_delayed_int + 3.11. cfg.set_delayed_string + 3.12. cfg.set_delayed + 3.13. cfg.del_delayed + 3.14. cfg.commit + 3.15. cfg.rollback + 3.16. cfg.help + 3.17. cfg.diff + 3.18. cfg.add_group_inst + 3.19. cfg.del_group_inst The module implements the RPC commands documented in the next sections. @@ -179,11 +183,21 @@ Chapter 1. Admin Guide # kamcmd cfg.sets voicemail srv_ip "1.2.3.4" ... -3.6. cfg.set_now_string +3.6. cfg.reset + + cfg.reset - Reset the variable values of a configuration group. The + function accepts only one parameter: group name. + + Example 1.5. Use cfg.reset RPC command +... +# kamcmd cfg.reset core +... + +3.7. cfg.set_now_string cfg.set_now_string - This is an alias to the command cfg.sets. -3.7. cfg.set +3.8. cfg.set cfg.set - Set the value of a configuration variable and commit the change immediately. This is a wrapper command for cfg.set_now_int and @@ -192,7 +206,7 @@ Chapter 1. Admin Guide int/string value. The group name can optionally contain the group instance id, for example foo[5]. -3.8. cfg.del +3.9. cfg.del cfg.del - Delete the value of a configuration variable from a group instance and commit the change immediately. The value is reset to the @@ -200,21 +214,21 @@ Chapter 1. Admin Guide two parameters: group name, variable name. The group name must contain the group instance id, for example foo[5]. -3.9. cfg.set_delayed_int +3.10. cfg.set_delayed_int cfg.set_delayed_int - Prepare the change of a configuration variable, but does not commit the new value yet. The function accepts three parameters: group name, variable name, integer value. The group name can optionally contain the group instance id, for example foo[5]. -3.10. cfg.set_delayed_string +3.11. cfg.set_delayed_string cfg.set_delayed_string - Prepare the change of a configuration variable, but does not commit the new value yet. The function accepts three parameters: group name, variable name, string value. The group name can optionally contain the group instance id, for example foo[5]. -3.11. cfg.set_delayed +3.12. cfg.set_delayed cfg.set_delayed - Prepare the change of a configuration variable, but does not commit the new value yet. This is a wrapper command for @@ -223,7 +237,7 @@ Chapter 1. Admin Guide variable name, int/string value. The group name can optionally contain the group instance id, for example foo[5]. -3.12. cfg.del_delayed +3.13. cfg.del_delayed cfg.del_delayed - Prepare the deletion of the value of a configuration variable from a group instance, but does not commit the change yet. The @@ -231,33 +245,33 @@ Chapter 1. Admin Guide The function accepts two parameters: group name, variable name. The group name must contain the group instance id, for example foo[5]. -3.13. cfg.commit +3.14. cfg.commit cfg.commit - Commit the previously prepared configuration changes. The function does not have any parameters. -3.14. cfg.rollback +3.15. cfg.rollback cfg.rollback - Drop the prepared configuration changes. The function does not have any parameters. -3.15. cfg.help +3.16. cfg.help cfg.help - Print the description of a configuration variable. The function accepts two parameters: group name, variable name. -3.16. cfg.diff +3.17. cfg.diff cfg.diff - List the pending configuration changes that have not been committed yet. The function does not have any parameters. -3.17. cfg.add_group_inst +3.18. cfg.add_group_inst cfg.add_group_inst - Add a new instance to an existing configuration group. The function accepts one parameter: group name[instance id], for example foo[5]. -3.18. cfg.del_group_inst +3.19. cfg.del_group_inst cfg.del_group_inst - Delete an instance of an existing configuration group. The function accepts one parameter: group name[instance id], for diff --git a/src/modules/cfg_rpc/cfg_rpc.c b/src/modules/cfg_rpc/cfg_rpc.c index b694d060881..06e775c5c11 100644 --- a/src/modules/cfg_rpc/cfg_rpc.c +++ b/src/modules/cfg_rpc/cfg_rpc.c @@ -355,6 +355,61 @@ static void rpc_get(rpc_t* rpc, void* c) } } +static const char* rpc_reset_doc[2] = { + "Reset all the values of a configuration group and commit the change immediately", + 0 +}; + +static void rpc_reset(rpc_t* rpc, void* c) +{ + void *h; + str gname, var; + cfg_def_t *def; + void *val; + int i, ret; + str group; + char *ch; + unsigned int *group_id; + unsigned int val_type; + unsigned int input_type; + + if (rpc->scan(c, "S", &group) < 1) + return; + + if (get_group_id(&group, &group_id)) { + rpc->fault(c, 400, "Wrong group syntax. Use either \"group\", or \"group[id]\""); + return; + } + + cfg_get_group_init(&h); + while(cfg_get_group_next(&h, &gname, &def)) + if (((gname.len == group.len) && (memcmp(gname.s, group.s, group.len) == 0))) + { + for (i=0; def[i].name; i++){ + + var.s = def[i].name; + var.len = (int)strlen(def[i].name); + ret = cfg_get_default_value_by_name(ctx, &gname, group_id, &var, + &val, &val_type); + + if (ret != 0) + continue; + + if (cfg_help(ctx, &group, &var, + &ch, &input_type) + ) { + rpc->fault(c, 400, "Failed to get the variable description"); + return; + } + + if (input_type == CFG_INPUT_INT) + cfg_set_now_int(ctx, &gname, group_id, &var, val); + else if (input_type == CFG_INPUT_STRING) + cfg_set_now_string(ctx, &gname, group_id, &var, val); + } + } +} + static const char* rpc_help_doc[2] = { "Print the description of a configuration variable", @@ -546,6 +601,7 @@ static rpc_export_t rpc_calls[] = { {"cfg.commit", rpc_commit, rpc_commit_doc, 0}, {"cfg.rollback", rpc_rollback, rpc_rollback_doc, 0}, {"cfg.get", rpc_get, rpc_get_doc, 0}, + {"cfg.reset", rpc_reset, rpc_reset_doc, 0}, {"cfg.help", rpc_help, rpc_help_doc, 0}, {"cfg.list", rpc_list, rpc_list_doc, 0}, {"cfg.diff", rpc_diff, rpc_diff_doc, 0}, diff --git a/src/modules/cfg_rpc/doc/rpc.xml b/src/modules/cfg_rpc/doc/rpc.xml index 9810762c50c..9298247d836 100644 --- a/src/modules/cfg_rpc/doc/rpc.xml +++ b/src/modules/cfg_rpc/doc/rpc.xml @@ -87,6 +87,22 @@ ... # &kamcmd; cfg.sets voicemail srv_ip "1.2.3.4" ... + + + +
+ cfg.reset + + cfg.reset - Reset the variable values of + a configuration group. The function accepts only one parameter: + group name. + + + Use <varname>cfg.reset</varname> RPC command + +... +# &sercmd; cfg.reset core +...