/** * Checks if the configuration is valid. The function checks if all * required parameters are set and adds default values if necessary. * @param cfg configuration */ void config_check(config_t *cfg) { int i, j; const char *s; double f; config_setting_t *cs, *vs; for (i = 0; defaults[i].name; i++) { /* Lookup setting group */ cs = config_lookup(cfg, defaults[i].group); if (!cs) cs = config_setting_add(config_root_setting(cfg), defaults[i].group, CONFIG_TYPE_GROUP); /* (1) Check for string */ if (defaults[i].type == CONFIG_TYPE_STRING) { if (config_setting_lookup_string(cs, defaults[i].name, &s)) continue; /* Add default value */ vs = config_setting_add(cs, defaults[i].name, CONFIG_TYPE_STRING); config_setting_set_string(vs, defaults[i].val.sval); /* (2) Check for float */ } else if (defaults[i].type == CONFIG_TYPE_FLOAT) { if (config_setting_lookup_float(cs, defaults[i].name, &f)) continue; /* Check for mis-interpreted integer */ if (config_setting_lookup_int(cs, defaults[i].name, &j)) { config_setting_remove(cs, defaults[i].name); vs = config_setting_add(cs, defaults[i].name, CONFIG_TYPE_FLOAT); config_setting_set_float(vs, (double) j); continue; } /* Add default value */ vs = config_setting_add(cs, defaults[i].name, CONFIG_TYPE_FLOAT); config_setting_set_float(vs, defaults[i].val.fval); /* (3) Check for integer */ } else if (defaults[i].type == CONFIG_TYPE_INT) { if (config_setting_lookup_int(cs, defaults[i].name, &j)) continue; /* Check for mis-interpreted float */ if (config_setting_lookup_float(cs, defaults[i].name, &f)) { config_setting_remove(cs, defaults[i].name); vs = config_setting_add(cs, defaults[i].name, CONFIG_TYPE_INT); config_setting_set_int(vs, (long) round(f)); continue; } /* Add default value */ vs = config_setting_add(cs, defaults[i].name, CONFIG_TYPE_INT); config_setting_set_int(vs, defaults[i].val.ival); } else { error("Unknown configuration type"); } } }
/********************** __get_unused_group_on_path find an unused group, DO NOT CREATE IT and return its name returned string must be freed return NULL on error **********************/ char * __get_unused_group_on_path(const char * table, const char * file, char * path) { char tag[7]; int index = 0; config_setting_t * setting; const config_t * config; SDL_LockMutex(entry_mutex); config = get_config(table,file); if(config==NULL) { SDL_UnlockMutex(entry_mutex); return NULL; } sprintf(tag,"A%05x",index); if(path != NULL) { setting = config_lookup(config,path); free(path); } else { setting = config_root_setting(config); } while( config_setting_add(setting,tag,CONFIG_TYPE_GROUP) == NULL ) { index++; sprintf(tag,"A%05x",index); } config_setting_remove(setting,tag); SDL_UnlockMutex(entry_mutex); return strdup(tag); }
ret_code_t entry_copy_aggregate(config_setting_t * source, config_setting_t * dest, int type) { const char * setting_name; config_setting_t * new_dest; int index=0; char tag[7]; setting_name = config_setting_name(source); if(setting_name == NULL) { return RET_NOK; } new_dest=config_setting_add(dest,setting_name,type); if( new_dest == NULL ) { // Try to find an available name sprintf(tag,"A%05x",index); while((new_dest=config_setting_add(dest,setting_name,type))== NULL) { index++; sprintf(tag,"A%05x",index); } } if(!entry_copy_config(source,new_dest)) { config_setting_remove(dest,setting_name); return RET_NOK; } return RET_OK; }
int main(int argc, char ** argv) { char * recname; config_t cfg; if(argc != 2) usage(argv[0]); recname = argv[1]; err = open(STATEFILE,O_RDWR); CHECK_ERR_LTZ("Open schedule file"); fd = err; err = flock(fd, LOCK_SH); CHECK_ERR("Lock statefile"); err = atexit(&exitfunc); config_init(&cfg); config_read_file(&cfg, STATEFILE); config_setting_t *root; root = config_root_setting(&cfg); err = config_setting_remove(root, recname); CHECK_CFG("Remove recording from schedule"); err = config_write_file(&cfg, STATEFILE); CHECK_CFG("Write config file"); config_destroy(&cfg); return 0; }
void patch_save() { config_setting_t* root_setting = config_root_setting(&patch_config); config_setting_remove(root_setting, CFG_MOD_MATRIX_CONTROLLER); config_setting_t* mod_matrix_patch = config_setting_add(root_setting, CFG_MOD_MATRIX_CONTROLLER, CONFIG_TYPE_GROUP); mod_matrix_controller_save(mod_matrix_patch); if (config_write_file(&patch_config, PATCH_FILE) != CONFIG_TRUE) { LOG_ERROR("Patch write error to %s", PATCH_FILE); } }
// {{{ session_delete_session() void session_delete_session(const char* user) { if(strlen(user)==0) return; struct config_t cfg; config_init(&cfg); config_setting_t *us; if(!config_read_file(&cfg, OD_SESSION_FILE)) config_write_file(&cfg, OD_SESSION_FILE); if( !(us = config_lookup(&cfg, user)) ) return; us = config_setting_remove(cfg.root, user); config_write_file(&cfg, OD_SESSION_FILE); config_destroy(&cfg); }
/********************* return RET_NOK on error *********************/ static ret_code_t __remove_group(const char * table, const char * file, const char * group, va_list ap) { const config_t * config; config_setting_t * setting = NULL; char * path; SDL_LockMutex(entry_mutex); config = get_config(table,file); if(config==NULL) { SDL_UnlockMutex(entry_mutex); return RET_NOK; } path = get_path(ap); if(path != NULL) { setting = config_lookup(config,path); free(path); } else { setting = config_root_setting(config); } if( setting == NULL ) { SDL_UnlockMutex(entry_mutex); return RET_NOK; } if( config_setting_remove(setting,group) == CONFIG_FALSE) { SDL_UnlockMutex(entry_mutex); return RET_NOK; } write_config(config,table,file); SDL_UnlockMutex(entry_mutex); return RET_OK; }
/** * Loads group configuration from config file into memory. * @private */ static void read_config(void) { config_setting_t *groups = NULL; const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name int group_count = 0; if (conf_read_file(&pc_group_config, config_filename)) return; groups = config_lookup(&pc_group_config, "groups"); if (groups != NULL) { GroupSettings *group_settings = NULL; DBIterator *iter = NULL; int i, loop = 0; group_count = config_setting_length(groups); for (i = 0; i < group_count; ++i) { int id = 0, level = 0; const char *groupname = NULL; int log_commands = 0; config_setting_t *group = config_setting_get_elem(groups, i); if (!config_setting_lookup_int(group, "id", &id)) { ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i); config_setting_remove_elem(groups, i); --i; --group_count; continue; } if (id2group(id) != NULL) { ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i); config_setting_remove_elem(groups, i); --i; --group_count; continue; } config_setting_lookup_int(group, "level", &level); config_setting_lookup_bool(group, "log_commands", &log_commands); if (!config_setting_lookup_string(group, "name", &groupname)) { char temp[20]; config_setting_t *name = NULL; snprintf(temp, sizeof(temp), "Group %d", id); if ((name = config_setting_add(group, "name", CONFIG_TYPE_STRING)) == NULL || !config_setting_set_string(name, temp)) { ShowError("pc_groups:read_config: failed to set missing group name, id=%d, skipping... (%s:%d)\n", id, config_setting_source_file(group), config_setting_source_line(group)); continue; } config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer } if (name2group(groupname) != NULL) { ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname); config_setting_remove_elem(groups, i); --i; --group_count; continue; } CREATE(group_settings, GroupSettings, 1); group_settings->id = id; group_settings->level = level; group_settings->name = groupname; group_settings->log_commands = (bool)log_commands; group_settings->inherit = config_setting_get_member(group, "inherit"); group_settings->commands = config_setting_get_member(group, "commands"); group_settings->permissions = config_setting_get_member(group, "permissions"); group_settings->inheritance_done = false; group_settings->root = group; group_settings->group_pos = i; strdb_put(pc_groupname_db, groupname, group_settings); idb_put(pc_group_db, id, group_settings); } group_count = config_setting_length(groups); // Save number of groups // Check if all commands and permissions exist iter = db_iterator(pc_group_db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions; int count = 0, j; // Make sure there is "commands" group if (commands == NULL) commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP); count = config_setting_length(commands); for (j = 0; j < count; ++j) { config_setting_t *command = config_setting_get_elem(commands, j); const char *name = config_setting_name(command); if (!atcommand_exists(name)) { ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name); config_setting_remove(commands, name); --j; --count; } } // Make sure there is "permissions" group if (permissions == NULL) permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP); count = config_setting_length(permissions); for(j = 0; j < count; ++j) { config_setting_t *permission = config_setting_get_elem(permissions, j); const char *name = config_setting_name(permission); int p; ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), p, strcmp(pc_g_permission_name[p].name, name) == 0); if (p == ARRAYLENGTH(pc_g_permission_name)) { ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name); config_setting_remove(permissions, name); --p; --count; } } } dbi_destroy(iter); // Apply inheritance i = 0; // counter for processed groups while (i < group_count) { iter = db_iterator(pc_group_db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *inherit = NULL, *commands = group_settings->commands, *permissions = group_settings->permissions; int j, inherit_count = 0, done = 0; if (group_settings->inheritance_done) // group already processed continue; if ((inherit = group_settings->inherit) == NULL || (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others ++i; group_settings->inheritance_done = true; continue; } for (j = 0; j < inherit_count; ++j) { GroupSettings *inherited_group = NULL; const char *groupname = config_setting_get_string_elem(inherit, j); if (groupname == NULL) { ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j); config_setting_remove_elem(inherit,j); continue; } if ((inherited_group = name2group(groupname)) == NULL) { ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname); config_setting_remove_elem(inherit,j); continue; } if (!inherited_group->inheritance_done) continue; // we need to do that group first // Copy settings (commands/permissions) that are not defined yet if (inherited_group->commands != NULL) { int l = 0, commands_count = config_setting_length(inherited_group->commands); for (l = 0; l < commands_count; ++l) config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, l)); } if (inherited_group->permissions != NULL) { int l = 0, permissions_count = config_setting_length(inherited_group->permissions); for (l = 0; l < permissions_count; ++l) config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, l)); } ++done; // copied commands and permissions from one of inherited groups } if (done == inherit_count) { // copied commands from all of inherited groups ++i; group_settings->inheritance_done = true; // we're done with this group } } dbi_destroy(iter); if (++loop > group_count) { ShowWarning("pc_groups:read_config: Could not process inheritance rules, check your config '%s' for cycles...\n", config_filename); break; } } // while(i < group_count) // Pack permissions into GroupSettings.e_permissions for faster checking iter = db_iterator(pc_group_db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *permissions = group_settings->permissions; int c, count = config_setting_length(permissions); for (c = 0; c < count; ++c) { config_setting_t *perm = config_setting_get_elem(permissions, c); const char *name = config_setting_name(perm); int val = config_setting_get_bool(perm); int j; if (val == 0) // does not have this permission continue; ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0); group_settings->e_permissions |= pc_g_permission_name[j].permission; } } dbi_destroy(iter); } ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename); if( ( pc_group_max = group_count ) ) { DBIterator *iter = db_iterator(pc_group_db); GroupSettings *group_settings = NULL; int* group_ids = aMalloc( pc_group_max * sizeof(int) ); int i = 0; for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { group_ids[i++] = group_settings->id; } atcommand_db_load_groups(group_ids); aFree(group_ids); dbi_destroy(iter); } }