static int
setup_f(void **state)
{
    (void)state;

    nc_verbosity(NC_VERB_VERBOSE);

    return 0;
}
Exemple #2
0
int cmd_verb(const char* arg) {
	const char* verb;

	verb = arg + 5;
	if (strcmp(verb, "error") == 0) {
		nc_verbosity(NC_VERB_ERROR);
	} else if (strcmp(verb, "warning") == 0) {
		nc_verbosity(NC_VERB_WARNING);
	} else if (strcmp(verb, "verbose") == 0) {
		nc_verbosity(NC_VERB_VERBOSE);
	} else if (strcmp(verb, "debug") == 0) {
		nc_verbosity(NC_VERB_DEBUG);
	} else {
		nc_verb_error("Unknown verbosity \"%s\"", verb);
		return 1;
	}

	return 0;
}
Exemple #3
0
static PyObject *setVerbosity(PyObject *self, PyObject *args, PyObject *keywds)
{
	int level = NC_VERB_ERROR; /* 0 */

	static char *kwlist[] = {"level", NULL};

	if (! PyArg_ParseTupleAndKeywords(args, keywds, "i", kwlist, &level)) {
		return NULL;
	}

	/* normalize level value if not from the enum */
	if (level < NC_VERB_ERROR) {
		nc_verbosity(NC_VERB_ERROR);
	} else if (level > NC_VERB_DEBUG) {
		nc_verbosity(NC_VERB_DEBUG);
	} else {
		nc_verbosity(level);
	}

	Py_RETURN_NONE;
}
Exemple #4
0
int main (int argc, char** argv)
{
	conn_t* conn = NULL;

	struct sigaction action;
	sigset_t block_mask;

	char *aux_string = NULL, path[PATH_MAX];
	int next_option, ret;
	int daemonize = 0, len;
	int verbose = 0;
	struct module * netopeer_module = NULL, *server_module = NULL;

	/* initialize message system and set verbose and debug variables */
	if ((aux_string = getenv (ENVIRONMENT_VERBOSE)) == NULL) {
		verbose = NC_VERB_ERROR;
	} else {
		verbose = atoi (aux_string);
	}

	aux_string = NULL; /* for sure to avoid unwanted changes in environment */

	/* parse given options */
	while ((next_option = getopt (argc, argv, OPTSTRING)) != -1) {
		switch (next_option) {
		case 'd':
			daemonize = 1;
			break;
		case 'h':
			print_usage (argv[0]);
			break;
		case 'v':
			verbose = atoi (optarg);
			break;
		case 'V':
			print_version (argv[0]);
			break;
		default:
			print_usage (argv[0]);
			break;
		}
	}

	/* set signal handler */
	sigfillset (&block_mask);
	action.sa_handler = signal_handler;
	action.sa_mask = block_mask;
	action.sa_flags = 0;
	sigaction (SIGINT, &action, NULL);
	sigaction (SIGQUIT, &action, NULL);
	sigaction (SIGABRT, &action, NULL);
	sigaction (SIGTERM, &action, NULL);
	sigaction (SIGKILL, &action, NULL);
	sigaction (SIGHUP, &action, NULL);

	nc_callback_print (clb_print);

	/* normalize value if not from the enum */
	if (verbose < NC_VERB_ERROR) {
		nc_verbosity (NC_VERB_ERROR);
	} else if (verbose > NC_VERB_DEBUG) {
		nc_verbosity (NC_VERB_DEBUG);
	} else {
		nc_verbosity (verbose);
	}

	/* go to the background as a daemon */
	if (daemonize == 1) {
		if (daemon(0, 0) != 0) {
			nc_verb_error("Going to background failed (%s)", strerror(errno));
			return (EXIT_FAILURE);
		}
		openlog("netopeer-server", LOG_PID, LOG_DAEMON);
	} else {
		openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON);
	}

	/* make sure we were executed by root */
	if (geteuid() != 0) {
		nc_verb_error("Failed to start, must have root privileges.");
		return (EXIT_FAILURE);
	}

	/*
	 * this initialize the library and check potential ABI mismatches
	 * between the version it was compiled for and the actual shared
	 * library used.
	 */
	LIBXML_TEST_VERSION

	/* initialize library including internal datastores and maybee something more */
	if ((ret = nc_init (NC_INIT_ALL | NC_INIT_MULTILAYER)) < 0) {
		nc_verb_error("Library initialization failed.");
		return (EXIT_FAILURE);
	}

	/* Initiate communication subsystem for communicate with agents */
	conn = comm_init(ret & NC_INITRET_RECOVERY);
	if (conn == NULL) {
		nc_verb_error("Communication subsystem not initiated.");
		return (EXIT_FAILURE);
	}

	server_start = 1;

restart:
	/* start NETCONF server module */
	if ((server_module = calloc(1, sizeof(struct module))) == NULL) {
		nc_verb_error("Creating necessary NETCONF server plugin failed!");
		comm_destroy(conn);
		return(EXIT_FAILURE);
	}
	server_module->name = strdup(NCSERVER_MODULE_NAME);
	if (module_enable(server_module, 0)) {
		nc_verb_error("Starting necessary NETCONF server plugin failed!");
		free(server_module->name);
		free(server_module);
		comm_destroy(conn);
		return EXIT_FAILURE;
	}

	/* start netopeer device module - it will start all modules that are
	 * in its configuration and in server configuration */
	if ((netopeer_module = calloc(1, sizeof(struct module))) == NULL) {
		nc_verb_error("Creating necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		comm_destroy(conn);
		return(EXIT_FAILURE);
	}
	netopeer_module->name = strdup(NETOPEER_MODULE_NAME);
	if (module_enable(netopeer_module, 0)) {
		nc_verb_error("Starting necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		free(netopeer_module->name);
		free(netopeer_module);
		comm_destroy(conn);
		return EXIT_FAILURE;
	}

	server_start = 0;
	nc_verb_verbose("Netopeer server successfully initialized.");

	while (!done) {
		comm_loop(conn, 500);
	}

	/* unload Netopeer module -> unload all modules */
	module_disable(server_module, 1);
	module_disable(netopeer_module, 1);

	/* main cleanup */

	if (!restart_soft) {
		/* close connection and destroy all sessions only when shutting down or hard restarting the server */
		comm_destroy(conn);
		server_sessions_destroy_all ();
		nc_close ();
	}

	/*
	 *Free the global variables that may
	 *have been allocated by the parser.
	 */
	xmlCleanupParser ();

	if (restart_soft) {
		nc_verb_verbose("Server is going to soft restart.");
		restart_soft = 0;
		done = 0;
		goto restart;
	} else if (restart_hard) {
		nc_verb_verbose("Server is going to hard restart.");
		len = readlink("/proc/self/exe", path, PATH_MAX);
		path[len] = 0;
		execv(path, argv);
	}

	return (EXIT_SUCCESS);
}
Exemple #5
0
void listen_loop(int do_init) {
	struct client_struct* new_client;
	struct np_sock npsock = {.count = 0};
	int ret;
	struct timespec ts;
#ifdef NP_SSH
	ssh_bind sshbind = NULL;
#endif
#ifdef NP_TLS
	SSL_CTX* tlsctx = NULL;
#endif

	/* Init */
	if (do_init) {
#ifdef NP_SSH
		np_ssh_init();
#endif
#ifdef NP_TLS
		np_tls_init();
#endif
		if ((ret = pthread_create(&netopeer_state.data_tid, NULL, data_thread, NULL)) != 0) {
			nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret));
			return;
		}
		if ((ret = pthread_create(&netopeer_state.netconf_rpc_tid, NULL, netconf_rpc_thread, NULL)) != 0) {
			nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret));
			return;
		}
	}

	/* Main accept loop */
	do {
		new_client = NULL;

		/* Binds change check */
		if (netopeer_options.binds_change_flag) {
			/* BINDS LOCK */
			pthread_mutex_lock(&netopeer_options.binds_lock);

			sock_cleanup(&npsock);
			sock_listen(netopeer_options.binds, &npsock);

			netopeer_options.binds_change_flag = 0;
			/* BINDS UNLOCK */
			pthread_mutex_unlock(&netopeer_options.binds_lock);

			if (npsock.count == 0) {
				nc_verb_warning("Server is not listening on any address!");
			}
		}

#ifdef NP_SSH
		sshbind = np_ssh_server_id_check(sshbind);
#endif
#ifdef NP_TLS
		tlsctx = np_tls_server_id_check(tlsctx);
#endif

#ifndef DISABLE_CALLHOME
		/* Callhome client check */
		if (callhome_client != NULL) {
			/* CALLHOME LOCK */
			pthread_mutex_lock(&callhome_lock);
			new_client = callhome_client;
			callhome_client = NULL;
			/* CALLHOME UNLOCK */
			pthread_mutex_unlock(&callhome_lock);
		}
#endif

		/* Listen client check */
		if (new_client == NULL) {
			new_client = sock_accept(&npsock);
		}

		/* New client full structure creation */
		if (new_client != NULL) {

			/* Maximum number of sessions check */
			if (netopeer_options.max_sessions > 0) {
				ret = 0;
#ifdef NP_SSH
				ret += np_ssh_session_count();
#endif
#ifdef NP_TLS
				ret += np_tls_session_count();
#endif

				if (ret >= netopeer_options.max_sessions) {
					nc_verb_error("Maximum number of sessions reached, droppping the new client.");
					new_client->to_free = 1;
					switch (new_client->transport) {
#ifdef NP_SSH
					case NC_TRANSPORT_SSH:
						client_free_ssh((struct client_struct_ssh*)new_client);
						break;
#endif
#ifdef NP_TLS
					case NC_TRANSPORT_TLS:
						client_free_tls((struct client_struct_tls*)new_client);
						break;
#endif
					default:
						nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__);
					}
					free(new_client);

					/* sleep to prevent clients from immediate connection retry */
					usleep(netopeer_options.response_time*1000);
					continue;
				}
			}

			switch (new_client->transport) {
#ifdef NP_SSH
			case NC_TRANSPORT_SSH:
				ret = np_ssh_create_client((struct client_struct_ssh*)new_client, sshbind);
				if (ret != 0) {
					new_client->to_free = 1;
					client_free_ssh((struct client_struct_ssh*)new_client);
				}
				break;
#endif
#ifdef NP_TLS
			case NC_TRANSPORT_TLS:
				ret = np_tls_create_client((struct client_struct_tls*)new_client, tlsctx);
				if (ret != 0) {
					new_client->to_free = 1;
					client_free_tls((struct client_struct_tls*)new_client);
				}
				break;
#endif
			default:
				nc_verb_error("Client with an unknown transport protocol, dropping it.");
				new_client->to_free = 1;
				ret = 1;
			}

			/* client is not valid, some error occured */
			if (ret != 0) {
				free(new_client);
				continue;
			}

			/* add the client into the global clients structure */
			/* GLOBAL WRITE LOCK */
			pthread_rwlock_wrlock(&netopeer_state.global_lock);
			client_append(&netopeer_state.clients, new_client);
			/* GLOBAL WRITE UNLOCK */
			pthread_rwlock_unlock(&netopeer_state.global_lock);
		}

	} while (!quit && !restart_soft);

	/* Cleanup */
	sock_cleanup(&npsock);
#ifdef NP_SSH
	ssh_bind_free(sshbind);
#endif
#ifdef NP_TLS
	SSL_CTX_free(tlsctx);
#endif
	if (!restart_soft) {
		if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
			nc_verb_warning("%s: failed to get time (%s)", strerror(errno));
		}
		ts.tv_sec += THREAD_JOIN_QUIT_TIMEOUT;

		/* wait for all the clients to exit nicely themselves */
		if ((ret = pthread_timedjoin_np(netopeer_state.netconf_rpc_tid, NULL, &ts)) != 0) {
			nc_verb_warning("%s: failed to join the netconf RPC thread (%s)", __func__, strerror(ret));
			if (ret == ETIMEDOUT) {
				pthread_cancel(netopeer_state.netconf_rpc_tid);
			}
		}
		if ((ret = pthread_timedjoin_np(netopeer_state.data_tid, NULL, &ts)) != 0) {
			nc_verb_warning("%s: failed to join the SSH data thread (%s)", __func__, strerror(ret));
			if (ret == ETIMEDOUT) {
				pthread_cancel(netopeer_state.data_tid);
			}
		}

#ifdef NP_SSH
		np_ssh_cleanup();
#endif
#ifdef NP_TLS
		np_tls_cleanup();
#endif
	}
}

int main(int argc, char** argv) {
	struct sigaction action;
	sigset_t block_mask;

	char *aux_string = NULL, path[PATH_MAX];
	int next_option;
	int daemonize = 0, len;
	int listen_init = 1;
	struct np_module* netopeer_module = NULL, *server_module = NULL;

	/* initialize message system and set verbose and debug variables */
	if ((aux_string = getenv(ENVIRONMENT_VERBOSE)) == NULL) {
		netopeer_options.verbose = NC_VERB_ERROR;
	} else {
		netopeer_options.verbose = atoi(aux_string);
	}

	aux_string = NULL; /* for sure to avoid unwanted changes in environment */

	/* parse given options */
	while ((next_option = getopt(argc, argv, OPTSTRING)) != -1) {
		switch (next_option) {
		case 'd':
			daemonize = 1;
			break;
		case 'h':
			print_usage(argv[0]);
			break;
		case 'v':
			netopeer_options.verbose = atoi(optarg);
			break;
		case 'V':
			print_version(argv[0]);
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}

	/* set signal handler */
	sigfillset (&block_mask);
	action.sa_handler = signal_handler;
	action.sa_mask = block_mask;
	action.sa_flags = 0;
	sigaction(SIGINT, &action, NULL);
	sigaction(SIGQUIT, &action, NULL);
	sigaction(SIGABRT, &action, NULL);
	sigaction(SIGTERM, &action, NULL);
	sigaction(SIGHUP, &action, NULL);

	nc_callback_print(clb_print);

	/* normalize value if not from the enum */
	if (netopeer_options.verbose > NC_VERB_DEBUG) {
		netopeer_options.verbose = NC_VERB_DEBUG;
	}
	nc_verbosity(netopeer_options.verbose);

	/* go to the background as a daemon */
	if (daemonize == 1) {
		if (daemon(0, 0) != 0) {
			nc_verb_error("Going to background failed (%s)", strerror(errno));
			return EXIT_FAILURE;
		}
		openlog("netopeer-server", LOG_PID, LOG_DAEMON);
	} else {
		openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON);
	}

	/* make sure we were executed by root */
	if (geteuid() != 0) {
		nc_verb_error("Failed to start, must have root privileges.");
		return EXIT_FAILURE;
	}

	/*
	 * this initialize the library and check potential ABI mismatches
	 * between the version it was compiled for and the actual shared
	 * library used.
	 */
	LIBXML_TEST_VERSION

	/* initialize library including internal datastores and maybee something more */
	if (nc_init(NC_INIT_ALL | NC_INIT_MULTILAYER) < 0) {
		nc_verb_error("Library initialization failed.");
		return EXIT_FAILURE;
	}

	server_start = 1;

restart:
	/* start NETCONF server module */
	if ((server_module = calloc(1, sizeof(struct np_module))) == NULL) {
		nc_verb_error("Creating necessary NETCONF server plugin failed!");
		return EXIT_FAILURE;
	}
	server_module->name = strdup(NCSERVER_MODULE_NAME);
	if (module_enable(server_module, 0)) {
		nc_verb_error("Starting necessary NETCONF server plugin failed!");
		free(server_module->name);
		free(server_module);
		return EXIT_FAILURE;
	}

	/* start netopeer device module - it will start all modules that are
	 * in its configuration and in server configuration */
	if ((netopeer_module = calloc(1, sizeof(struct np_module))) == NULL) {
		nc_verb_error("Creating necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		return EXIT_FAILURE;
	}
	netopeer_module->name = strdup(NETOPEER_MODULE_NAME);
	if (module_enable(netopeer_module, 0)) {
		nc_verb_error("Starting necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		free(netopeer_module->name);
		free(netopeer_module);
		return EXIT_FAILURE;
	}

	server_start = 0;
	nc_verb_verbose("Netopeer server successfully initialized.");

	listen_loop(listen_init);

	/* unload Netopeer module -> unload all modules */
	module_disable(server_module, 1);
	module_disable(netopeer_module, 1);

	/* main cleanup */

	if (!restart_soft) {
		/* close libnetconf only when shutting down or hard restarting the server */
		nc_close();
	}

	if (restart_soft) {
		nc_verb_verbose("Server is going to soft restart.");
		restart_soft = 0;
		listen_init = 0;
		goto restart;
	} else if (restart_hard) {
		nc_verb_verbose("Server is going to hard restart.");
		len = readlink("/proc/self/exe", path, PATH_MAX);
		path[len] = 0;
		xmlCleanupParser();
		execv(path, argv);
	}

	/*
	 *Free the global variables that may
	 *have been allocated by the parser.
	 */
	xmlCleanupParser();

	return EXIT_SUCCESS;
}
Exemple #6
0
int main(int argc, char* argv[])
{
	char* event, *stream, **list, *desc, *start;
	int i, c;
	int verbosity = NC_VERB_ERROR;
	int listing = 0;
	int corrupted = 0;
	int time_start = 0, time_end = -1;
	xmlDocPtr eventDoc;

	while ((c = getopt(argc, argv, ARGUMENTS)) != -1) {
		switch (c) {
		case 'h': /* Show help */
			usage(argv[0]);
			return EXIT_SUCCESS;

		case 'l': /* list the streams */
			listing = 1;
			break;

		case 's': /* time range - start */
			time_start = nc_datetime2time(optarg);
			break;

		case 'e': /* time range - end */
			time_end = nc_datetime2time(optarg);
			break;

		case 'v': /* Verbose operation */
			verbosity = atoi(optarg);
			if (verbosity < NC_VERB_ERROR) {
				verbosity = NC_VERB_ERROR;
			} else if (verbosity > NC_VERB_DEBUG) {
				verbosity = NC_VERB_DEBUG;
			}
			break;

		default:
			fprintf(stderr, "unknown argument -%c", optopt);
			break;
		}
	}

	if (!listing && (argc - optind) != 1) {
		if ((argc - optind) < 1) {
			fprintf(stderr, "Missing stream name\n\n");
		} else { /* (argc - optind) > 1 */
			fprintf(stderr, "Only a single stream name is allowed\n\n");
		}
		usage(argv[0]);
		return (EXIT_FAILURE);
	}
	stream = argv[optind];

	nc_verbosity(verbosity);
	nc_callback_print(clb_print);

	c = nc_init(NC_INIT_NOTIF);
	if (c == -1) {
		fprintf(stderr, "libnetconf initiation failed.");
		return (EXIT_FAILURE);
	}

	if (listing) {
		list = ncntf_stream_list();
		if (list == NULL || list[0] == NULL) {
			fprintf(stderr, "There is no NETCONF Event Stream.\n");
			return (EXIT_FAILURE);
		}
		fprintf(stdout, "NETCONF Event Stream list:\n");
		for (i = 0; list[i] != NULL; i++) {
			if (ncntf_stream_info(list[i], &desc, &start) == 0) {
				fprintf(stdout, "\t%s\n\t\t%s\n\t\t%s\n", list[i], desc, start);
				free(desc);
				free(start);
			}
			free(list[i]);
		}
		fprintf(stdout, "\n");
		free(list);

		return(EXIT_SUCCESS);
	}

	i = 0;
	ncntf_stream_iter_start(stream);
	while((event = ncntf_stream_iter_next(stream, time_start, time_end, NULL)) != NULL) {
		if ((eventDoc = xmlReadMemory(event, strlen(event), NULL, NULL, 0)) != NULL) {
			fprintf(stdout, "Event:\n");
			xmlDocFormatDump(stdout, eventDoc, 1);
			xmlFreeDoc(eventDoc);
			i++;
		} else {
			fprintf(stdout, "Invalid event format.\n");
			corrupted = 1;
		}
		free(event);
	}
	ncntf_stream_iter_finish(stream);

	/* print summary */
	fprintf(stdout, "\nSummary:\n\tNumber of records: %d\n", i);
	if (corrupted) {
		fprintf(stdout, "\tSTREAM FILE IS CORRUPTED!\n");
	}

	ncntf_close();

	return (EXIT_SUCCESS);
}
Exemple #7
0
int
main(int argc, char **argv)
{
    const char *optstring = "d:fhv:";

    const struct option longopts[] = {
        {"db", required_argument, 0, 'd'},
        {"foreground", no_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {"verbose", required_argument, 0, 'v'},
        {0, 0, 0, 0}
    };
    int longindex, next_option;
    int verbose = 0;
    int retval = EXIT_SUCCESS, r;
    char *aux_string;
    struct sigaction action;
    sigset_t block_mask;

    struct {
        struct ncds_ds *server;
        ncds_id server_id;
        struct ncds_ds *ofc;
        ncds_id ofc_id;
    } ds = {NULL, -1, NULL, -1};

    /* connection channel to agents */
    comm_t *c = NULL;

    /* initialize message system and set verbose and debug variables */
    if ((aux_string = getenv(ENVIRONMENT_VERBOSE)) == NULL) {
        /* default verbose level */
        verbose = NC_VERB_ERROR;
    } else {
        verbose = atoi(aux_string);
    }

    /* parse given options */
    while ((next_option = getopt_long(argc, argv, optstring, longopts,
                                      &longindex)) != -1) {
        switch (next_option) {
        case 'd':
            ovsdb_path = strdup(optarg);
            break;
        case 'f':
            ofc_daemonize = 0;
            break;
        case 'h':
            print_usage(argv[0]);
            break;
        case 'v':
            verbose = atoi(optarg);
            break;
        default:
            print_usage(argv[0]);
            break;
        }
    }

    /* set signal handler */
    sigfillset(&block_mask);
    action.sa_handler = signal_handler;
    action.sa_mask = block_mask;
    action.sa_flags = 0;
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGQUIT, &action, NULL);
    sigaction(SIGABRT, &action, NULL);
    sigaction(SIGTERM, &action, NULL);
    sigaction(SIGKILL, &action, NULL);

    /* set verbose message printer callback */
    nc_callback_print(clb_print);

    /* normalize value if not from the enum */
    if (verbose < NC_VERB_ERROR) {
        nc_verbosity(NC_VERB_ERROR);
    } else if (verbose > NC_VERB_DEBUG) {
        nc_verbosity(NC_VERB_DEBUG);
    } else {
        nc_verbosity(verbose);
    }

    /* go to the background as a daemon */
    if (ofc_daemonize == 1) {
        if (daemon(0, 0) != 0) {
            nc_verb_error("Going to background failed (%s)", strerror(errno));
            return (EXIT_FAILURE);
        }
        openlog("ofc-server", LOG_PID, LOG_DAEMON);
    } else {
        openlog("ofc-server", LOG_PID | LOG_PERROR, LOG_DAEMON);
    }

    /* make sure we have sufficient rights to communicate with OVSDB */
    /* TODO */

    /* init libnetconf for a multilayer server */
    r = nc_init((NC_INIT_ALL & ~NC_INIT_NACM) | NC_INIT_MULTILAYER);
    if (r < 0) {
        nc_verb_error("libnetconf initialization failed.");
        return (EXIT_FAILURE);
    }

    /* Initiate communication subsystem for communication with agents */
    if ((c = comm_init(r)) == NULL) {
        nc_verb_error("Communication subsystem not initiated.");
        return (EXIT_FAILURE);
    }

    /* prepare the ietf-netconf-server module */
    ncds_add_model(OFC_DATADIR
                   "/ietf-netconf-server/ietf-x509-cert-to-name.yin");
    ds.server =
        ncds_new_transapi_static(NCDS_TYPE_FILE,
                                 OFC_DATADIR
                                 "/ietf-netconf-server/ietf-netconf-server.yin",
                                 &server_transapi);
    if (ds.server == NULL) {
        retval = EXIT_FAILURE;
        nc_verb_error("Creating ietf-netconf-server datastore failed.");
        goto cleanup;
    }
    ncds_file_set_path(ds.server,
                       OFC_DATADIR "/ietf-netconf-server/datastore.xml");
    ncds_feature_enable("ietf-netconf-server", "ssh");
    ncds_feature_enable("ietf-netconf-server", "inbound-ssh");
    if ((ds.server_id = ncds_init(ds.server)) < 0) {
        retval = EXIT_FAILURE;
        nc_verb_error
            ("Initiating ietf-netconf-server datastore failed (error code %d).",
             ds.ofc_id);
        goto cleanup;
    }

    /* prepare the of-config module */
    ds.ofc = ncds_new_transapi_static(NCDS_TYPE_CUSTOM,
                                      OFC_DATADIR "/of-config/of-config.yin",
                                      &ofc_transapi);
    if (ds.ofc == NULL) {
        retval = EXIT_FAILURE;
        nc_verb_error("Creating of-config datastore failed.");
        goto cleanup;
    }
    ncds_custom_set_data(ds.ofc, NULL, &ofcds_funcs);
    if ((ds.ofc_id = ncds_init(ds.ofc)) < 0) {
        retval = EXIT_FAILURE;
        nc_verb_error("Initiating of-config datastore failed (error code %d).",
                      ds.ofc_id);
        goto cleanup;
    }

    if (ncds_consolidate() != 0) {
        retval = EXIT_FAILURE;
        nc_verb_error("Consolidating data models failed.");
        goto cleanup;
    }

    if (ncds_device_init(&(ds.server_id), NULL, 1) != 0) {
        retval = EXIT_FAILURE;
        nc_verb_error("Initiating ietf-netconf-server module failed.");
        goto cleanup;
    }

    if (ncds_device_init(&(ds.ofc_id), NULL, 1) != 0) {
        retval = EXIT_FAILURE;
        nc_verb_error("Initiating of-config module failed.");
        goto cleanup;
    }

    nc_verb_verbose("OF-CONFIG server successfully initialized.");

    while (!mainloop) {
        comm_loop(c, 500);
    }

cleanup:

    /* cleanup */
    nc_close();

    return (retval);
}