/* * dnsutl - utilities to make DNS easier to configure * Copyright (C) 1996, 1999, 2003, 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 #include #include static string_ty * substitute(string_ty *orig, symtab_ty *stp) { static char *buffer; static size_t bufmax; size_t bufpos; char *s; char *ep; string_ty *name; srrf_t *rp; string_ty *value; bufpos = 0; for (s = orig->str_text; *s; ++s) { if (*s != '$') { normal: if (bufpos >= bufmax) { bufmax += 1000; buffer = mem_change_size(buffer, bufmax); } buffer[bufpos++] = *s; continue; } ++s; if (!*s) return 0; if (*s == '$') { ++s; goto normal; } if (!isalpha(*s)) return 0; /* * collect the name */ ep = s + 1; while (*ep && isalpha(*ep)) ++ep; name = str_n_from_c(s, ep - s); s = ep - 1; /* * see if there is such a named row */ rp = symtab_query(stp, name); if (!rp) return 0; if (rp->arg.nstrings != 1) return 0; /* * copy the value into the result buffer */ value = rp->arg.string[0]; while (bufpos + value->str_length > bufmax) { bufmax = bufmax * 2 + 64; buffer = mem_change_size(buffer, bufmax); } memcpy(buffer + bufpos, value->str_text, value->str_length); bufpos += value->str_length; } return str_n_from_c(buffer, bufpos); } static void sp_check_arguments(srrf_t *rp) { if (rp->arg.string[1]->str_text[0] != '/') srrf_lex_error("the path must be absolute"); } static void sp_output(srrf_t *rp, void *arg) { string_ty *name; string_ty *abs_name; string_ty *s; srrf_bootparam_aux_ty *aux; srrf_t *rp2; static srrf_type_ty *in_a_type; aux = arg; name = substitute(rp->arg.string[0], aux->substitute); if (!name) { output_error_locn ( rp->file_name->str_text, rp->line_number, "illegal \"%s\" substitution", rp->arg.string[0]->str_text ); name = str_copy(rp->arg.string[0]); } abs_name = srrf_relative_to_absolute(name); str_free(name); if (!in_a_type) { srrf_class_ty *in_class; in_class = srrf_class_by_name("in"); assert(in_class); in_a_type = srrf_type_by_name(in_class, "a"); } rp2 = symtab_query(aux->name_stp, abs_name); if (!rp2) { output_error_locn ( rp->file_name->str_text, rp->line_number, "host \"%s\" does not exist", abs_name->str_text ); } else if (rp2->type != in_a_type) { output_error_locn ( rp->file_name->str_text, rp->line_number, "host \"%s\" is an alias, suggest \"%s\" instead", abs_name->str_text, rp2->arg.string[0]->str_text ); } name = srrf_absolute_to_relative(abs_name); str_free(abs_name); output_printf("%s=%s", rp->type->name, name->str_text); str_free(name); s = substitute(rp->arg.string[1], aux->substitute); if (!s) { output_error_locn ( rp->file_name->str_text, rp->line_number, "illegal \"%s\" substitution", rp->arg.string[1]->str_text ); s = str_copy(rp->arg.string[1]); } output_printf(":%s", s->str_text); str_free(s); } static void one_output(srrf_t *rp, void *arg) { (void)arg; output_printf("%s=:%s", rp->type->name, rp->arg.string[0]->str_text); } static void server_check_arguments(srrf_t *rp) { string_ty *tmp; tmp = rp->arg.string[0]; rp->arg.string[0] = srrf_relative_to_absolute(tmp); str_free(tmp); } static int server_local_test(srrf_t *rp) { return srrf_private_domain_member(rp->arg.string[0]); } static void server_abs_to_rel(srrf_t *rp) { string_ty *s; s = rp->arg.string[0]; rp->arg.string[0] = srrf_absolute_to_relative(s); str_free(s); } static srrf_type_ty type[] = { { /* application architecture */ "aarch", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { "boottype", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { /* for i386/i86pc */ "display", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { "dump", 2, /* number of arguments */ sp_check_arguments, 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ sp_output, 0, }, { "install", 2, /* number of arguments */ sp_check_arguments, 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ sp_output, 0, }, { "install_config", 2, /* number of arguments */ sp_check_arguments, 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ sp_output, 0, }, { /* kernel architecture */ "karch", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { /* for i386/i86pc */ "keyboard", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { /* for i386/i86pc */ "mouse", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, { "root", 2, /* number of arguments */ sp_check_arguments, 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ sp_output, 0, }, { "server", 1, /* number of arguments */ server_check_arguments, server_local_test, 0, /* print */ server_abs_to_rel, one_output, 0, }, { "swap", 2, /* number of arguments */ sp_check_arguments, 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ sp_output, 0, }, { /* terminal type */ "term", 1, /* number of arguments */ 0, /* check_arguments */ 0, /* local_test */ 0, /* print */ 0, /* abs_to_rel */ one_output, 0, }, }; /* * This symbol describes the class. * It should be the only symbol exported from this file. */ srrf_class_ty srrf_class_bootparams = { "bootparam", type, SIZEOF(type) };