# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <dirent.h>
# include <assert.h>
# include <unistd.h>
# include <ctype.h>
# include <time.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "config_zkt.h"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
# include <getopt.h>
#endif
# include "debug.h"
# include "misc.h"
# include "zfparse.h"
# include "zconf.h"
extern int optopt;
extern int opterr;
extern int optind;
extern char *optarg;
const char *progname;
static const char *view = "";
static int writeflag = 0;
static int allflag = 0;
static int testflag = 0;
# define short_options ":aC:c:O:dlstvwV:rh"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
static struct option long_options[] = {
{"compability", required_argument, NULL, 'C'},
{"config", required_argument, NULL, 'c'},
{"option", required_argument, NULL, 'O'},
{"config-option", required_argument, NULL, 'O'},
{"default", no_argument, NULL, 'd'},
{"sidecfg", no_argument, NULL, 's'},
{"localcfg", no_argument, NULL, 'l'},
{"all-values", no_argument, NULL, 'a'},
{"test", no_argument, NULL, 't'},
{"overwrite", no_argument, NULL, 'w'},
{"version", no_argument, NULL, 'v' },
{"write", no_argument, NULL, 'w'},
{"view", required_argument, NULL, 'V' },
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
#endif
static void usage (char *mesg);
int main (int argc, char *argv[])
{
int c;
int opt_index;
int action;
int major;
int minor;
const char *file;
const char *defconfname = NULL;
const char *confname = NULL;
char *p;
char str[254+1];
zconf_t *refconfig = NULL;
zconf_t *config;
progname = *argv;
if ( (p = strrchr (progname, '/')) )
progname = ++p;
view = getnameappendix (progname, "zkt-conf");
defconfname = getdefconfname (view);
dbg_val0 ("Load built in config \"%s\"\n");
config = loadconfig ("", (zconf_t *)NULL);
if ( fileexist (defconfname) )
{
dbg_val ("Load site wide config file \"%s\"\n", defconfname);
config = loadconfig (defconfname, config);
}
if ( config == NULL )
fatal ("Out of memory\n");
confname = defconfname;
opterr = 0;
opt_index = 0;
action = 0;
setconfigversion (100);
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
while ( (c = getopt_long (argc, argv, short_options, long_options, &opt_index)) != -1 )
#else
while ( (c = getopt (argc, argv, short_options)) != -1 )
#endif
{
switch ( c )
{
case 'V':
view = optarg;
defconfname = getdefconfname (view);
if ( fileexist (defconfname) )
config = loadconfig (defconfname, config);
if ( config == NULL )
fatal ("Out of memory\n");
confname = defconfname;
break;
case 'O':
config = loadconfig_fromstr (optarg, config);
break;
case 'C':
switch ( sscanf (optarg, "%d.%d", &major, &minor) )
{
case 2: major = major * 100 + minor;
case 1: break;
default:
usage ("illegal release number");
}
setconfigversion (major);
break;
case 'c':
if ( *optarg == '\0' )
usage ("empty config file name");
config = loadconfig (optarg, config);
if ( *optarg == '-' || strcmp (optarg, "stdin") == 0 )
confname = "stdout";
else
confname = optarg;
break;
case 'd':
config = loadconfig ("", config);
confname = defconfname;
break;
case 's':
break;
case 'a':
allflag = 1;
break;
case 'l':
refconfig = dupconfig (config);
confname = LOCALCONF_FILE;
if ( fileexist (LOCALCONF_FILE) )
{
dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE);
config = loadconfig (LOCALCONF_FILE, config);
}
else if ( !writeflag )
usage ("error: no local config file found");
break;
case 't':
testflag = 1;
break;
case 'v':
fprintf (stderr, "%s version %s compiled for BIND version %d\n",
progname, ZKT_VERSION, BIND_VERSION);
fprintf (stderr, "ZKT %s\n", ZKT_COPYRIGHT);
return 0;
break;
case 'w':
writeflag = 1;
break;
case 'h':
usage ("");
break;
case ':':
snprintf (str, sizeof(str), "option \"-%c\" requires an argument.",
optopt);
usage (str);
break;
case '?':
if ( isprint (optopt) )
snprintf (str, sizeof(str), "Unknown option \"-%c\".",
optopt);
else
snprintf (str, sizeof (str), "Unknown option char \\x%x.",
optopt);
usage (str);
break;
default:
abort();
}
}
c = optind;
if ( c >= argc )
{
if ( testflag )
{
if ( checkconfig (config) )
fprintf (stderr, "All config file parameter seems to be ok\n");
}
else
{
if ( !writeflag )
confname = "stdout";
if ( refconfig )
if ( allflag )
printconfig (confname, config);
else
printconfigdiff (confname, refconfig, config);
else
printconfig (confname, config);
}
}
else
{
long minttl;
long maxttl;
int keydbfound;
char *dnskeydb;
file = argv[c++];
dnskeydb = config->keyfile;
minttl = 0x7FFFFFFF;
maxttl = 0;
keydbfound = parsezonefile (file, &minttl, &maxttl, dnskeydb);
if ( keydbfound < 0 )
error ("can't parse zone file %s\n", file);
if ( dnskeydb && !keydbfound )
{
if ( writeflag )
{
addkeydb (file, dnskeydb);
printf ("\"$INCLUDE %s\" directive added to \"%s\"\n", dnskeydb, file);
}
else
printf ("\"$INCLUDE %s\" should be added to \"%s\" (run with option -w)\n",
dnskeydb, file);
}
if ( minttl < (10 * MINSEC) )
fprintf (stderr, "Min_TTL of %s (%ld seconds) is too low to use it in a signed zone (see RFC4641)\n",
timeint2str (minttl), minttl);
else
fprintf (stderr, "Min_TTL:\t%s\t# (%ld seconds)\n", timeint2str (minttl), minttl);
fprintf (stdout, "Max_TTL:\t%s\t# (%ld seconds)\n", timeint2str (maxttl), maxttl);
if ( writeflag )
{
refconfig = dupconfig (config);
confname = LOCALCONF_FILE;
if ( fileexist (LOCALCONF_FILE) )
{
dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE);
config = loadconfig (LOCALCONF_FILE, config);
}
setconfigpar (config, "Max_TTL", &maxttl);
printconfigdiff (confname, refconfig, config);
}
}
return 0;
}
# define sopt_usage(mesg, value) fprintf (stderr, mesg, value)
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
# define lopt_usage(mesg, value) fprintf (stderr, mesg, value)
# define loptstr(lstr, sstr) lstr
#else
# define lopt_usage(mesg, value)
# define loptstr(lstr, sstr) sstr
#endif
static void usage (char *mesg)
{
fprintf (stderr, "%s version %s\n", progname, ZKT_VERSION);
if ( mesg && *mesg )
fprintf (stderr, "%s\n", mesg);
fprintf (stderr, "\n");
fprintf (stderr, "usage: %s -h\n", progname);
fprintf (stderr, "usage: %s [-V view] [-w|-t] -d [-O <optstr>]\n", progname);
fprintf (stderr, "usage: %s [-V view] [-w|-t] [-s] [-c config] [-O <optstr>]\n", progname);
fprintf (stderr, "usage: %s [-V view] [-w|-t] [-a] -l [-c config] [-O <optstr>]\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, "usage: %s [-c config] [-w] <zonefile>\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, " -V name%s", loptstr (", --view=name\n", ""));
fprintf (stderr, "\t\t specify the view name \n");
fprintf (stderr, " -d%s\tprint built-in default config parameter\n", loptstr (", --default", ""));
fprintf (stderr, " -s%s\tprint site wide config file parameter (this is the default)\n", loptstr (", --sitecfg", ""));
fprintf (stderr, " -l%s\tprint local config file parameter\n", loptstr (", --localcfg", ""));
fprintf (stderr, " -a%s\tprint all parameter not only the different one\n", loptstr (", --all", ""));
fprintf (stderr, " -c file%s", loptstr (", --config=file\n", ""));
fprintf (stderr, " \t\tread config from <file> instead of %s\n", CONFIG_FILE);
fprintf (stderr, " -O optstr%s", loptstr (", --config-option=\"optstr\"\n", ""));
fprintf (stderr, " \t\tread config options from commandline\n");
fprintf (stderr, " -t%s\ttest the config parameter if they are useful \n", loptstr (", --test", "\t"));
fprintf (stderr, " -w%s\twrite or rewrite config file \n", loptstr (", --write", "\t"));
fprintf (stderr, " -h%s\tprint this help \n", loptstr (", --help", "\t"));
exit (1);
}