コード例 #1
0
ファイル: settings.c プロジェクト: acasaccia/openomf
void settings_load_fields(void *st, const field *fields, int nfields) {
    for(int i=0;i < nfields;++i) {
        const field *f = &fields[i];
        switch(f->type) {
            case TYPE_INT:
                *fieldint(st, f->offset) = conf_int(f->name);
                break;

            case TYPE_FLOAT:
                *fieldfloat(st, f->offset) = conf_float(f->name);
                break;

            case TYPE_BOOL:
                *fieldbool(st, f->offset) = conf_bool(f->name);
                break;

            case TYPE_STRING:
                {
                    // make a copy of the string
                    char **s = fieldstr(st, f->offset);
                    if(*s) {
                        free(*s);
                    }
                    const char *s2 = conf_string(f->name);
                    *s = malloc(strlen(s2)+1);
                    strcpy(*s, s2);
                }
                break;
        }
    }
}
コード例 #2
0
ファイル: handlers.c プロジェクト: idtek/knot
int event_load(conf_t *conf, zone_t *zone)
{
	assert(zone);

	/* Take zone file mtime and load it. */
	char *filename = conf_zonefile(conf, zone->name);
	time_t mtime = zonefile_mtime(filename);
	free(filename);
	uint32_t dnssec_refresh = time(NULL);

	zone_contents_t *contents = NULL;
	int ret = zone_load_contents(conf, zone->name, &contents);
	if (ret != KNOT_EOK) {
		goto fail;
	}

	/* Store zonefile serial and apply changes from the journal. */
	zone->zonefile_serial = zone_contents_serial(contents);
	ret = zone_load_journal(conf, zone, contents);
	if (ret != KNOT_EOK) {
		goto fail;
	}

	/* Post load actions - calculate delta, sign with DNSSEC... */
	/*! \todo issue #242 dnssec signing should occur in the special event */
	ret = zone_load_post(conf, zone, contents, &dnssec_refresh);
	if (ret != KNOT_EOK) {
		if (ret == KNOT_ESPACE) {
			log_zone_error(zone->name, "journal size is too small "
			               "to fit the changes");
		} else {
			log_zone_error(zone->name, "failed to store changes into "
			               "journal (%s)", knot_strerror(ret));
		}
		goto fail;
	}

	/* Check zone contents consistency. */
	ret = zone_load_check(conf, contents);
	if (ret != KNOT_EOK) {
		goto fail;
	}

	/* Everything went alright, switch the contents. */
	zone->zonefile_mtime = mtime;
	zone_contents_t *old = zone_switch_contents(zone, contents);
	zone->flags &= ~ZONE_EXPIRED;
	uint32_t old_serial = zone_contents_serial(old);
	if (old != NULL) {
		synchronize_rcu();
		zone_contents_deep_free(&old);
	}

	/* Schedule notify and refresh after load. */
	if (zone_is_slave(conf, zone)) {
		zone_events_schedule(zone, ZONE_EVENT_REFRESH, ZONE_EVENT_NOW);
	}
	if (!zone_contents_is_empty(contents)) {
		zone_events_schedule(zone, ZONE_EVENT_NOTIFY, ZONE_EVENT_NOW);
		zone->bootstrap_retry = ZONE_EVENT_NOW;
	}

	/* Schedule zone resign. */
	conf_val_t val = conf_zone_get(conf, C_DNSSEC_SIGNING, zone->name);
	if (conf_bool(&val)) {
		schedule_dnssec(zone, dnssec_refresh);
	}

	/* Periodic execution. */
	val = conf_zone_get(conf, C_ZONEFILE_SYNC, zone->name);
	int64_t sync_timeout = conf_int(&val);
	if (sync_timeout >= 0) {
		zone_events_schedule(zone, ZONE_EVENT_FLUSH, sync_timeout);
	}

	uint32_t current_serial = zone_contents_serial(zone->contents);
	log_zone_info(zone->name, "loaded, serial %u -> %u",
	              old_serial, current_serial);

	return KNOT_EOK;

fail:
	zone_contents_deep_free(&contents);

	/* Try to bootstrap the zone if local error. */
	if (zone_is_slave(conf, zone) && !zone_events_is_scheduled(zone, ZONE_EVENT_XFER)) {
		zone_events_schedule(zone, ZONE_EVENT_XFER, ZONE_EVENT_NOW);
	}

	return ret;
}
コード例 #3
0
ファイル: main.c プロジェクト: gitter-badger/knot
int main(int argc, char **argv)
{
	/* Parse command line arguments. */
	int c = 0, li = 0;
	int daemonize = 0;
	const char *config_fn = CONF_DEFAULT_FILE;
	const char *config_db = NULL;
	const char *daemon_root = "/";

	/* Long options. */
	struct option opts[] = {
		{"config",    required_argument, 0, 'c' },
		{"confdb",    required_argument, 0, 'C' },
		{"daemonize", optional_argument, 0, 'd'},
		{"version",   no_argument,       0, 'V'},
		{"help",      no_argument,       0, 'h'},
		{0, 0, 0, 0}
	};

	while ((c = getopt_long(argc, argv, "c:C:dVh", opts, &li)) != -1) {
		switch (c) {
		case 'c':
			config_fn = optarg;
			break;
		case 'C':
			config_db = optarg;
			break;
		case 'd':
			daemonize = 1;
			if (optarg) {
				daemon_root = optarg;
			}
			break;
		case 'V':
			printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION);
			return EXIT_SUCCESS;
		case 'h':
		case '?':
			help();
			return EXIT_SUCCESS;
		default:
			help();
			return EXIT_FAILURE;
		}
	}

	/* Check for non-option parameters. */
	if (argc - optind > 0) {
		help();
		return EXIT_FAILURE;
	}

	/* Now check if we want to daemonize. */
	if (daemonize) {
		if (make_daemon(1, 0) != 0) {
			fprintf(stderr, "Daemonization failed, shutting down...\n");
			return EXIT_FAILURE;
		}
	}

	/* Clear file creation mask. */
	umask(0);

	/* Setup base signal handling. */
	setup_signals();

	/* Initialize cryptographic backend. */
	dnssec_crypto_init();
	atexit(dnssec_crypto_cleanup);

	/* Initialize pseudorandom number generator. */
	srand(time(NULL));

	/* POSIX 1003.1e capabilities. */
	setup_capabilities();

	/* Default logging to std out/err. */
	log_init();

	/* Open configuration. */
	conf_t *new_conf = NULL;
	if (config_db == NULL) {
		int ret = conf_new(&new_conf, conf_scheme, NULL);
		if (ret != KNOT_EOK) {
			log_fatal("failed to initialize configuration database "
			          "(%s)", knot_strerror(ret));
			log_close();
			return EXIT_FAILURE;
		}

		/* Import the configuration file. */
		ret = conf_import(new_conf, config_fn, true);
		if (ret != KNOT_EOK) {
			log_fatal("failed to load configuration file (%s)",
			          knot_strerror(ret));
			conf_free(new_conf, false);
			log_close();
			return EXIT_FAILURE;
		}

		new_conf->filename = strdup(config_fn);
	} else {
		/* Open configuration database. */
		int ret = conf_new(&new_conf, conf_scheme, config_db);
		if (ret != KNOT_EOK) {
			log_fatal("failed to open configuration database '%s' "
			          "(%s)", config_db, knot_strerror(ret));
			log_close();
			return EXIT_FAILURE;
		}
	}

	/* Run post-open config operations. */
	int res = conf_post_open(new_conf);
	if (res != KNOT_EOK) {
		log_fatal("failed to use configuration (%s)", knot_strerror(res));
		conf_free(new_conf, false);
		log_close();
		return EXIT_FAILURE;
	}

	conf_update(new_conf);

	/* Initialize logging subsystem. */
	log_reconfigure(conf(), NULL);

	/* Initialize server. */
	server_t server;
	res = server_init(&server, conf_bg_threads(conf()));
	if (res != KNOT_EOK) {
		log_fatal("failed to initialize server (%s)", knot_strerror(res));
		conf_free(conf(), false);
		log_close();
		return EXIT_FAILURE;
	}

	/* Reconfigure server interfaces.
	 * @note This MUST be done before we drop privileges. */
	server_reconfigure(conf(), &server);
	log_info("configured %zu zones", conf_id_count(conf(), C_ZONE));

	/* Alter privileges. */
	int uid, gid;
	if (conf_user(conf(), &uid, &gid) != KNOT_EOK ||
	    log_update_privileges(uid, gid) != KNOT_EOK ||
	    proc_update_privileges(uid, gid) != KNOT_EOK) {
		log_fatal("failed to drop privileges");
		server_deinit(&server);
		conf_free(conf(), false);
		log_close();
		return EXIT_FAILURE;
	}

	/* Check and create PID file. */
	long pid = (long)getpid();
	char *pidfile = NULL;
	if (daemonize) {
		pidfile = pid_check_and_create();
		if (pidfile == NULL) {
			server_deinit(&server);
			conf_free(conf(), false);
			log_close();
			return EXIT_FAILURE;
		}

		log_info("PID stored in '%s'", pidfile);
		if (chdir(daemon_root) != 0) {
			log_warning("failed to change working directory to %s",
			            daemon_root);
		} else {
			log_info("changed directory to %s", daemon_root);
		}
	}

	/* Now we're going multithreaded. */
	rcu_register_thread();

	/* Populate zone database. */
	log_info("loading zones");
	server_update_zones(conf(), &server);

	/* Check number of loaded zones. */
	if (knot_zonedb_size(server.zone_db) == 0) {
		log_warning("no zones loaded");
	}

	/* Start it up. */
	log_info("starting server");
	conf_val_t async_val = conf_get(conf(), C_SRV, C_ASYNC_START);
	res = server_start(&server, conf_bool(&async_val));
	if (res != KNOT_EOK) {
		log_fatal("failed to start server (%s)", knot_strerror(res));
		server_deinit(&server);
		rcu_unregister_thread();
		pid_cleanup(pidfile);
		log_close();
		conf_free(conf(), false);
		return EXIT_FAILURE;
	}

	if (daemonize) {
		log_info("server started as a daemon, PID %ld", pid);
	} else {
		log_info("server started in the foreground, PID %ld", pid);
		init_signal_started();
	}

	/* Start the event loop. */
	event_loop(&server);

	/* Teardown server and configuration. */
	server_deinit(&server);

	/* Free configuration. */
	conf_free(conf(), false);

	/* Unhook from RCU. */
	rcu_unregister_thread();

	/* Cleanup PID file. */
	pid_cleanup(pidfile);

	log_info("shutting down");
	log_close();

	return EXIT_SUCCESS;
}