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