/*
* 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);
}