/*
 * dnsutl - utilities to make DNS easier to configure
 * Copyright (C) 1999, 2001, 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 <http://www.gnu.org/licenses/>.
 */

#include <ac/stdio.h>
#include <ac/string.h>
#include <ac/unistd.h>

#include <error.h>
#include <hosts.h>
#include <map_hosts.h>
#include <srrf.h>
#include <srrf/origin.h>


int             verbose;
static const char *domain;


static string_ty *
get_domain_name(void)
{
    char            buffer[1000];
    const char      *tmp;
    const char      *ep;

    if (domain && *domain)
        tmp = domain;
    else
    {
#ifdef HAVE_GETDOMAINNAME
        if (getdomainname(buffer, sizeof(buffer)))
            nfatal("getdomainname");
        tmp = buffer;
        if (!*tmp)
#endif
            tmp = "example.com";
    }
    ep = strrchr(tmp, '.');
    if (ep && ep[1] == 0)
        return str_from_c(tmp);
    return str_format("%s.", tmp);
}


void
hosts(const char *infile, const char *outfile)
{
    FILE            *fp;
    srrf_t          *rp;
    srrf_t          *rp2;
    string_ty       *s;
    string_ty       *s2;
    srrf_class_ty   *in_class;
    srrf_type_ty    *in_ns_type;
    static const char *const soa[] =
    {
        "",     /* server */
        "",     /* hostmaster */
        "3",    /* seral */
        "10800", /* refresh: 3 hours */
        "1800", /* retry: 30 minutes */
        "604800", /* expire: 1 week */
        "86400", /* minimum: 1 day */
    };

    /*
     * open the input file
     */
    map_host_open(infile);

    /*
     * open the output file
     */
    if (outfile)
    {
        fp = fopen(outfile, "w");
        if (!fp)
            nfatal("creat \"%s\"", outfile);
    }
    else
    {
        outfile = "(stdout)";
        fp = stdout;
    }

    /*
     * write the origin
     */
    s = get_domain_name();
    srrf_origin_set(s);
    srrf_origin_print(fp);
    str_free(s);

    /*
     * write the SOA record
     */
    rp = srrf_alloc();
    rp->name = str_copy(s);
    rp->class = srrf_class_by_name("in");
    assert(rp->class);
    rp->type = srrf_type_by_name(rp->class, "soa");
    assert(rp->type);
    strlist_append(&rp->arg, srrf_origin_get());
    s2 = str_format("hostmaster.%s", srrf_origin_get()->str_text);
    strlist_append(&rp->arg, s2);
    str_free(s2);
    while (rp->arg.nstrings < SIZEOF(soa))
    {
        s2 = str_from_c(soa[rp->arg.nstrings]);
        strlist_append(&rp->arg, s2);
        str_free(s2);
    }
    fprintf(fp, "$ttl %d\n", 8 * 60 * 60);
    srrf_print(fp, rp);

    /*
     * Print a name server record.
     */
    fprintf(fp, "; This is an example name server record, you\n");
    fprintf(fp, "; will probably need to edit this for your site.\n");
    in_class = srrf_class_by_name("in");
    assert(in_class);
    in_ns_type = srrf_type_by_name(in_class, "ns");
    assert(in_ns_type);
    rp2 = srrf_alloc();
    rp2->name = str_copy(rp->name);
    rp2->class = in_class;
    rp2->type = in_ns_type;
    s2 = str_format("ns.%s", srrf_origin_get()->str_text);
    strlist_append(&rp2->arg, s2);
    str_free(s2);
    if (rp->file_name)
        rp2->file_name = str_copy(rp->file_name);
    rp2->line_number = rp->line_number;
    srrf_print(fp, rp2);
    srrf_free(rp2);
    srrf_free(rp);

    /*
     * convert the format
     */
    for (;;)
    {
        map_host_t      *mhp;
        size_t          j;

        mhp = map_host_read();
        if (!mhp)
            break;
        rp = srrf_alloc();
        rp->name = srrf_relative_to_absolute(mhp->name.string[0]);
        rp->class = srrf_class_by_name("in");
        rp->type = srrf_type_by_name(rp->class, "a");
        strlist_append(&rp->arg, mhp->address);
        srrf_print(fp, rp);
        srrf_free(rp);
        for (j = 1; j < mhp->name.nstrings; ++j)
        {
            rp = srrf_alloc();
            rp->name = srrf_relative_to_absolute(mhp->name.string[j]);
            rp->class = srrf_class_by_name("in");
            rp->type = srrf_type_by_name(rp->class, "cname");
            strlist_append(&rp->arg, mhp->name.string[0]);
            srrf_print(fp, rp);
            srrf_free(rp);
        }
        map_host_delete(mhp);
    }

    /*
     * close the files
     */
    map_host_close();
    if (fflush(fp))
        nfatal("write \"%s\"", outfile);
    if (fp != stdout && fclose(fp))
        nfatal("close \"%s\"", outfile);
}


void
hosts_domain(const char *s)
{
    domain = s;
}


syntax highlighted by Code2HTML, v. 0.9.1