/*
 * dnsutl - utilities to make DNS easier to configure
 * Copyright (C) 1996, 1999, 2000, 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/string.h>

#include <srrf/origin.h>
#include <srrf/private.h>
#include <str.h>


static string_ty *origin;


void
srrf_origin_set(string_ty *s)
{
    if (origin)
    {
        str_free(origin);
        origin = 0;
    }
    if (s)
    {
        origin = str_copy(s);
        if (origin->str_text[origin->str_length - 1] != '.')
            srrf_lex_error("origin must be absolute");
    }
}


string_ty *
srrf_origin_get(void)
{
    return origin;
}


string_ty *
srrf_relative_to_absolute(string_ty *s)
{
    static string_ty *dot;
    static string_ty *dot_dot;
    static string_ty *at;

    if (!dot)
        dot = str_from_c(".");
    if (!dot_dot)
        dot_dot = str_from_c("..");
    if (!at)
        at = str_from_c("@");

    if (str_equal(s, dot_dot))
        return str_copy(dot);
    if (s->str_length >= 1 && s->str_text[s->str_length - 1] == '.')
        return str_copy(s);
    if (!origin)
    {
        srrf_lex_error("no origin specified");
        origin = str_from_c("b.o.g.u.s.");
    }
    if (str_equal(s, at))
        return str_copy(origin);
    if (str_equal(origin, dot))
        return str_format("%s.", s->str_text);
    return str_format("%s.%s", s->str_text, origin->str_text);
}


string_ty *
srrf_absolute_to_relative(string_ty *name)
{
    if (!origin)
        return str_copy(name);
    if (str_equal(origin, name))
        return str_from_c("@");
    if
    (
        origin->str_length + 1 < name->str_length
    &&
        name->str_text[name->str_length - origin->str_length - 1] == '.'
    &&
        !memcmp
        (
            name->str_text + name->str_length - origin->str_length,
            origin->str_text,
            origin->str_length
        )
    )
    {
        return
            str_n_from_c
            (
                name->str_text,
                name->str_length - origin->str_length - 1
            );
    }
    return str_copy(name);
}


void
srrf_origin_print(FILE *fp)
{
    if (!origin)
        return;
    fprintf(fp, "$origin %s\n", origin->str_text);
}


syntax highlighted by Code2HTML, v. 0.9.1