/* * dnsutl - utilities to make DNS easier to configure * Copyright (C) 1991-1993, 1995, 1996, 1999, 2006, 2007 Peter Miller * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include int verbose; int delete_foreign_names; static string_ty * first_part(string_ty *s) { char *dot; dot = strchr(s->str_text, '.'); if (!dot) return str_from_c(""); return str_n_from_c(s->str_text, dot - s->str_text); } static string_ty * no_trailing_dot(string_ty *s) { if (s->str_length < 2 || s->str_text[s->str_length - 1] != '.') return str_copy(s); return str_n_from_c(s->str_text, s->str_length - 1); } static void cname_reap(void *p) { strlist_ty *slp; slp = p; strlist_free(p); mem_free(p); } void hosts(const char *infile, const char *outfile) { FILE *fp; srrf_t *rp; srrf_list_ty *rlp; size_t j, k; srrf_t *kp; string_ty *tmp; string_ty *tmp2; srrf_class_ty *in_class; srrf_type_ty *in_hinfo_type; srrf_type_ty *in_cname_type; srrf_type_ty *in_a_type; symtab_ty *hinfo_stp; symtab_ty *cname_stp; strlist_ty *slp; /* * find the magic stuff */ in_class = srrf_class_by_name("in"); assert(in_class); in_hinfo_type = srrf_type_by_name(in_class, "hinfo"); assert(in_hinfo_type); in_cname_type = srrf_type_by_name(in_class, "cname"); assert(in_cname_type); in_a_type = srrf_type_by_name(in_class, "a"); assert(in_a_type); /* * read the input file */ rlp = srrf_reader(infile, verbose, delete_foreign_names); /* * remember cname and hinfo records */ hinfo_stp = symtab_alloc(5); cname_stp = symtab_alloc(5); cname_stp->reap = cname_reap; for (j = 0; j < rlp->nrecords; ++j) { rp = rlp->record[j]; if (rp->type == in_hinfo_type) symtab_assign(hinfo_stp, rp->name, rp); if (rp->type == in_cname_type) { slp = symtab_query(cname_stp, rp->arg.string[0]); if (!slp) { slp = mem_alloc(sizeof(strlist_ty)); strlist_zero(slp); symtab_assign(cname_stp, rp->arg.string[0], slp); } strlist_append_unique(slp, rp->name); } } /* * open the output file */ if (outfile) { fp = fopen(outfile, "w"); if (!fp) nfatal("creat \"%s\"", outfile); } else { outfile = "(stdout)"; fp = stdout; } /* * warning comment at the top of the file */ fprintf(fp, "# Do not edit this file. It is generated\n"); fprintf ( fp, "# using a '%s %s %s' command.\n", progname, (infile ? infile : "-"), (fp == stdout ? "-" : outfile) ); /* * scan the resources looking for hosts */ for (j = 0; j < rlp->nrecords; ++j) { rp = rlp->record[j]; if (rp->type != in_a_type) continue; /* * Print the address and the name. * Given the fully qualified domain name as an alias. */ tmp = first_part(rp->name); fprintf(fp, "%s %s", rp->arg.string[0]->str_text, tmp->str_text); tmp2 = no_trailing_dot(rp->name); if (!str_equal(tmp, tmp2)) { fprintf(fp, " %s", tmp2->str_text); } str_free(tmp); str_free(tmp2); /* * search for aliases */ slp = symtab_query(cname_stp, rp->name); if (slp) { for (k = 0; k < slp->nstrings; ++k) { string_ty *name; name = slp->string[k]; tmp = first_part(name); fprintf(fp, " "); fprintf(fp, "%s", tmp->str_text); tmp2 = no_trailing_dot(name); if (!str_equal(tmp, tmp2)) fprintf(fp, " %s", tmp2->str_text); str_free(tmp); str_free(tmp2); } } /* * search for host info */ kp = symtab_query(hinfo_stp, rp->name); if (kp) { fprintf ( fp, " # %s, %s", kp->arg.string[0]->str_text, kp->arg.string[1]->str_text ); } fprintf(fp, "\n"); } symtab_free(hinfo_stp); symtab_free(cname_stp); srrf_list_free(rlp); /* * close the output file */ if (fflush(fp)) nfatal("write \"%s\"", outfile); if (fp != stdout && fclose(fp)) nfatal("close \"%s\"", outfile); }