/** * Stores the routing data rd in config_file * * @param rd Pointer to the routing tree which shall be saved to file * * @return 0 means ok, -1 means an error occurred */ int save_config(struct route_data_t * rd) { FILE * outfile; int i,j; if(backup_config() < 0){ return -1; } if ((outfile = fopen(config_file, "w")) == NULL) { LM_ERR("Could not open config file %s\n", config_file); return -1; } i = 0; if (rd->carrier_num>=1) { for (j=0; j< rd->carriers[i]->domain_num; j++) { fprintf(outfile, "domain %.*s {\n", rd->carriers[i]->domains[j]->name->len, rd->carriers[i]->domains[j]->name->s); if (save_route_data_recursor(rd->carriers[i]->domains[j]->tree, outfile) < 0) { goto errout; } fprintf(outfile, "}\n\n"); } } fclose(outfile); return 0; errout: fclose(outfile); LM_ERR("Cannot save config file %s\n", config_file); return -1; }
/** * Does the work for save_config, traverses the routing data tree * and writes each rule to file. * * @param rt the current route tree node * @param outfile the filehandle to which the config data is written * * @return 0 on success, -1 on failure */ static int save_route_data_recursor(struct route_tree_item * rt, FILE * outfile) { int i; struct route_rule * rr; struct route_rule_p_list * rl; if (rt->rule_list) { rr = rt->rule_list; fprintf(outfile, "\tprefix %s {\n", rr->prefix.len ? rr->prefix.s : "NULL"); fprintf(outfile, "\t\tmax_targets = %i\n\n", rt->max_targets); while (rr) { fprintf(outfile, "\t\ttarget %s {\n", rr->host.len ? rr->host.s : "NULL"); fprintf(outfile, "\t\t\tprob = %f\n", rr->orig_prob); fprintf(outfile, "\t\t\thash_index = %i\n", rr->hash_index); fprintf(outfile, "\t\t\tstatus = %i\n", rr->status); if (rr->strip > 0) { fprintf(outfile, "\t\t\tstrip = \"%i\"\n", rr->strip); } if (rr->local_prefix.len) { fprintf(outfile, "\t\t\trewrite_prefix = \"%.*s\"\n", rr->local_prefix.len, rr->local_prefix.s); } if (rr->local_suffix.len) { fprintf(outfile, "\t\t\trewrite_suffix: \"%.*s\"\n", rr->local_suffix.len, rr->local_suffix.s); } if (rr->backup) { fprintf(outfile, "\t\t\tbackup = %i\n", rr->backup->hash_index); } if (rr->backed_up) { rl = rr->backed_up; fprintf(outfile, "\t\t\tbacked_up = {"); i=0; while (rl) { if (i>0) { fprintf(outfile, ", "); } fprintf(outfile, "%i", rl->hash_index); rl = rl->next; i++; } fprintf(outfile, "}\n"); } if (rr->comment.len) { fprintf(outfile, "\t\t\tcomment = \"%.*s\"\n", rr->comment.len, rr->comment.s); } fprintf(outfile, "\t\t}\n"); rr = rr->next; } fprintf(outfile, "\t}\n"); } for (i = 0; i < 10; i++) { if (rt->nodes[i]) { if (save_route_data_recursor(rt->nodes[i], outfile) < 0) { return -1; } } } return 0; }
/** * Does the work for save_config, traverses the routing data tree * and writes each rule to file. * * @param node the current prefix tree node * @param outfile the filehandle to which the config data is written * * @return 0 on success, -1 on failure */ static int save_route_data_recursor(struct dtrie_node_t * node, FILE * outfile) { int i; struct route_flags *rf; struct route_rule * rr; struct route_rule_p_list * rl; str *tmp_str; str null_str = str_init("NULL"); /* no support for flag lists in route config */ rf = (struct route_flags *)(node->data); if (rf && rf->rule_list) { rr = rf->rule_list; tmp_str = (rr->prefix.len ? &rr->prefix : &null_str); fprintf(outfile, "\tprefix %.*s {\n", tmp_str->len, tmp_str->s); fprintf(outfile, "\t\tmax_targets = %i\n\n", rf->max_targets); while (rr) { tmp_str = (rr->host.len ? &rr->host : &null_str); fprintf(outfile, "\t\ttarget %.*s {\n", tmp_str->len, tmp_str->s); fprintf(outfile, "\t\t\tprob = %f\n", rr->orig_prob); fprintf(outfile, "\t\t\thash_index = %i\n", rr->hash_index); fprintf(outfile, "\t\t\tstatus = %i\n", rr->status); if (rr->strip > 0) { fprintf(outfile, "\t\t\tstrip = \"%i\"\n", rr->strip); } if (rr->local_prefix.len) { fprintf(outfile, "\t\t\trewrite_prefix = \"%.*s\"\n", rr->local_prefix.len, rr->local_prefix.s); } if (rr->local_suffix.len) { fprintf(outfile, "\t\t\trewrite_suffix: \"%.*s\"\n", rr->local_suffix.len, rr->local_suffix.s); } if (rr->backup) { fprintf(outfile, "\t\t\tbackup = %i\n", rr->backup->hash_index); } if (rr->backed_up) { rl = rr->backed_up; fprintf(outfile, "\t\t\tbacked_up = {"); i=0; while (rl) { if (i>0) { fprintf(outfile, ", "); } fprintf(outfile, "%i", rl->hash_index); rl = rl->next; i++; } fprintf(outfile, "}\n"); } if (rr->comment.len) { fprintf(outfile, "\t\t\tcomment = \"%.*s\"\n", rr->comment.len, rr->comment.s); } fprintf(outfile, "\t\t}\n"); rr = rr->next; } fprintf(outfile, "\t}\n"); } for (i = 0; i < cr_match_mode; i++) { if (node->child[i]) { if (save_route_data_recursor(node->child[i], outfile) < 0) { return -1; } } } return 0; }