Пример #1
0
static void handle_options(int argc, char **argv)
{
	while (1) {
		int option_index = 0, c;
		static struct option long_options[] = {
			{"help", 0, 0, 'h'},
			{"debug", 1, 0, 'd'},
			{"daemonize", 0, 0, 'D'},
			{"config-file", 1, 0, 'c'},
			{"disable-color", 0, 0, 's'},
			{"timestamp", 0, 0, 'T'},
			{"local", 1, 0, 'l'},
			{"log-level", 1, 0, 'e'},
			{"rf-ctl", 1, 0, 'r'},
			{"testmode", 0, 0, 't'},
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, "hd:DsTc:e:r:t",
				long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_usage();
			print_help();
			exit(0);
		case 's':
			log_set_use_color(osmo_stderr_target, 0);
			break;
		case 'd':
			log_parse_category_mask(osmo_stderr_target, optarg);
			break;
		case 'D':
			daemonize = 1;
			break;
		case 'c':
			config_file = strdup(optarg);
			break;
		case 'T':
			log_set_print_timestamp(osmo_stderr_target, 1);
			break;
		case 'e':
			log_set_log_level(osmo_stderr_target, atoi(optarg));
			break;
		case 'r':
			rf_ctl = optarg;
			break;
		default:
			/* ignore */
			break;
		}
	}
}
Пример #2
0
int main(void)
{
	osmo_init_logging(&log_info);
	log_set_log_level(osmo_stderr_target, LOGL_INFO);

	test_error();
	test_auth_not_avail();
	test_auth_then_ciph1();
	test_auth_then_ciph2();
	test_auth_reuse();
	test_auth_reuse_key_seq_mismatch();
	return 0;
}
int main(int argc, char *argv[])
{
	int teip;

	tall_test = talloc_named_const(NULL, 1, "lapd_test");

	osmo_init_logging(&lapd_test_log_info);
	log_set_log_level(osmo_stderr_target, LOGL_NOTICE);

	/*
	 * initialize datagram server.
	 */

	conn = osmo_dgram_create(tall_test);
	if (conn == NULL) {
		fprintf(stderr, "cannot create client\n");
		exit(EXIT_FAILURE);
	}
	osmo_dgram_set_local_addr(conn, "127.0.0.1");
	osmo_dgram_set_local_port(conn, 10001);
	osmo_dgram_set_remote_addr(conn, "127.0.0.1");
	osmo_dgram_set_remote_port(conn, 10000);
	osmo_dgram_set_read_cb(conn, read_cb);

	lapd = lapd_instance_alloc(1, lapd_tx_cb, conn, lapd_rx_cb, conn,
				   &lapd_profile_sat);
	if (lapd == NULL) {
		LOGP(DLAPDTEST, LOGL_ERROR, "cannot allocate instance\n");
		exit(EXIT_FAILURE);
	}

	teip = lapd_tei_alloc(lapd, tei);
	if (teip == 0) {
		LOGP(DLAPDTEST, LOGL_ERROR, "cannot assign TEI\n");
		exit(EXIT_FAILURE);
	}

	if (osmo_dgram_open(conn) < 0) {
		fprintf(stderr, "cannot open client\n");
		exit(EXIT_FAILURE);
	}

	LOGP(DLAPDTEST, LOGL_NOTICE, "Entering main loop\n");

	while(1) {
		osmo_select_main(0);
	}
}
Пример #4
0
static Octstr *httpd_loglevel(List *cgivars, int status_type)
{
    Octstr *reply;
    Octstr *level;
    int new_loglevel;
    
    if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
    if ((reply = httpd_check_status())!= NULL) return reply;
 
    /* check if new loglevel is given */
    level = http_cgi_variable(cgivars, "level");
    if (level) {
        new_loglevel = atoi(octstr_get_cstr(level));
        log_set_log_level(new_loglevel);
        return octstr_format("log-level set to %d", new_loglevel);
    }
    else {
        return octstr_create("New level not given");
    }
}
int l23_app_init(struct osmocom_ms *ms)
{
	int rc;

	srand(time(NULL));

//	log_parse_category_mask(stderr_target, "DL1C:DRSL:DRR:DGPS:DSUM");
	log_parse_category_mask(stderr_target, "DSUM");
	log_set_log_level(stderr_target, LOGL_INFO);

	l23_app_work = _scan_work;
	l23_app_exit = _scan_exit;

	rc = scan_init(ms);
	if (rc)
		return rc;

	l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
	printf("Mobile initialized, please start phone now!\n");
	return 0;
}
Пример #6
0
static void handle_options(struct cmdline_cfg *ccfg, int argc, char **argv)
{
	while (1) {
		int option_index = 0, c;
		static struct option long_options[] = {
			{"help", 0, 0, 'h'},
			{"debug", 1, 0, 'd'},
			{"daemonize", 0, 0, 'D'},
			{"config-file", 1, 0, 'c'},
			{"disable-color", 0, 0, 's'},
			{"timestamp", 0, 0, 'T'},
			{"log-level", 1, 0, 'e'},
			{"restart-file", 1, 0, 'r'},
			{NULL, 0, 0, 0}
		};

		c = getopt_long(argc, argv, "hd:Dc:sTe:r:",
				long_options, &option_index);
		if (c == -1) {
			if (optind < argc) {
				LOGP(DGTPHUB, LOGL_FATAL,
				     "Excess commandline arguments ('%s').\n",
				     argv[optind]);
				exit(2);
			}
			break;
		}

		switch (c) {
		case 'h':
			//print_usage();
			print_help(ccfg);
			exit(0);
		case 's':
			log_set_use_color(osmo_stderr_target, 0);
			break;
		case 'd':
			if (strcmp("list", optarg) == 0) {
				list_categories();
				exit(0);
			} else
				log_parse_category_mask(osmo_stderr_target, optarg);
			break;
		case 'D':
			ccfg->daemonize = 1;
			break;
		case 'c':
			ccfg->config_file = optarg;
			break;
		case 'T':
			log_set_print_timestamp(osmo_stderr_target, 1);
			break;
		case 'e':
			log_set_log_level(osmo_stderr_target, atoi(optarg));
			break;
		case 'r':
			ccfg->restart_counter_file = optarg;
			break;
		default:
			LOGP(DGTPHUB, LOGL_FATAL, "Invalid command line argument, abort.\n");
			exit(1);
			break;
		}
	}
}
Пример #7
0
int main(int argc, char *argv[])
{
	FILE *infp, *outfp;
	int type, n, i;
	char *p;
	struct node_mcc *mcc;
	struct node_mnc *mnc;
	struct node_lac *lac;
	struct node_cell *cell;
	struct node_meas *meas;

	log_init(&log_info, NULL);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);
	log_set_all_filter(stderr_target, 1);
	log_parse_category_mask(stderr_target, "Dxxx");
	log_set_log_level(stderr_target, LOGL_INFO);

	if (argc <= 2) {
usage:
		fprintf(stderr, "Usage: %s <file.log> <file.kml> "
			"[lines] [debug]\n", argv[0]);
		fprintf(stderr, "lines: Add lines between cell and "
			"Measurement point\n");
		fprintf(stderr, "debug: Add debugging of location algorithm.\n"
			);
		return 0;
	}

	for (i = 3; i < argc; i++) {
		if (!strcmp(argv[i], "lines"))
			log_lines = 1;
		else if (!strcmp(argv[i], "debug"))
			log_debug = 1;
		else goto usage;
	}

	infp = fopen(argv[1], "r");
	if (!infp) {
		fprintf(stderr, "Failed to open '%s' for reading\n", argv[1]);
		return -EIO;
	}

	while ((type = read_log(infp))) {
		switch (type) {
		case LOG_TYPE_SYSINFO:
			add_sysinfo();
			break;
		case LOG_TYPE_POWER:
			add_power();
			break;
		}
	}

	fclose(infp);

	if (!strcmp(argv[2], "-"))
		outfp = stdout;
	else
		outfp = fopen(argv[2], "w");
	if (!outfp) {
		fprintf(stderr, "Failed to open '%s' for writing\n", argv[2]);
		return -EIO;
	}

	/* document name */
	p = argv[2];
	while (strchr(p, '/'))
		p = strchr(p, '/') + 1;

	kml_header(outfp, p);
	mcc = node_mcc_first;
	while (mcc) {
	  printf("MCC: %02x\n", mcc->mcc);
	 /* folder open */
	  fprintf(outfp, "\t<Folder>\n");
	  fprintf(outfp, "\t\t<name>MCC %s (%s)</name>\n",
		gsm_print_mcc(mcc->mcc), gsm_get_mcc(mcc->mcc));
	  fprintf(outfp, "\t\t<open>0</open>\n");
	  mnc = mcc->mnc;
	  while (mnc) {
	    printf(" MNC: %02x\n", mnc->mnc);
	    /* folder open */
	    fprintf(outfp, "\t\t<Folder>\n");
	    fprintf(outfp, "\t\t\t<name>MNC %s (%s)</name>\n",
	    	gsm_print_mnc(mnc->mnc), gsm_get_mnc(mcc->mcc, mnc->mnc));
	    fprintf(outfp, "\t\t\t<open>0</open>\n");
	    lac = mnc->lac;
	    while (lac) {
	      printf("  LAC: %04x\n", lac->lac);
	      /* folder open */
	      fprintf(outfp, "\t\t\t<Folder>\n");
	      fprintf(outfp, "\t\t\t\t<name>LAC %04x</name>\n", lac->lac);
	      fprintf(outfp, "\t\t\t\t<open>0</open>\n");
	      cell = lac->cell;
	      while (cell) {
		printf("   CELL: %04x\n", cell->cellid);
		fprintf(outfp, "\t\t\t\t<Folder>\n");
		fprintf(outfp, "\t\t\t\t\t<name>CELL-ID %04x</name>\n", cell->cellid);
		fprintf(outfp, "\t\t\t\t\t<open>0</open>\n");
		meas = cell->meas;
		n = 0;
		while (meas) {
			if (meas->ta_valid)
				printf("    TA: %d\n", meas->ta);
			if (meas->gps_valid)
				kml_meas(outfp, meas, ++n, mcc->mcc, mnc->mnc,
					lac->lac, cell->cellid);
			meas = meas->next;
		}
		kml_cell(outfp, cell);
		/* folder close */
		fprintf(outfp, "\t\t\t\t</Folder>\n");
		cell = cell->next;
	      }
	      /* folder close */
	      fprintf(outfp, "\t\t\t</Folder>\n");
	      lac = lac->next;
	    }
	    /* folder close */
	    fprintf(outfp, "\t\t</Folder>\n");
	    mnc = mnc->next;
	  }
	  /* folder close */
	  fprintf(outfp, "\t</Folder>\n");
	  mcc = mcc->next;
	}
#if 0
	FIXME: power
	/* folder open */
	fprintf(outfp, "\t<Folder>\n");
	fprintf(outfp, "\t\t<name>Power</name>\n");
	fprintf(outfp, "\t\t<open>0</open>\n");
	power = node_power_first;
	n = 0;
	while (power) {
		/* folder open */
		fprintf(outfp, "\t\t<Folder>\n");
		fprintf(outfp, "\t\t\t<name>Power %d</name>\n", ++n);
		fprintf(outfp, "\t\t\t<open>0</open>\n");
		/* folder close */
		fprintf(outfp, "\t\t</Folder>\n");
		power = power->next;
	}
	/* folder close */
	fprintf(outfp, "\t</Folder>\n");
#endif
	kml_footer(outfp);

	fclose(outfp);

	return 0;
}
Пример #8
0
/* FIXME: finally get some option parsing code into libosmocore */
static void handle_options(int argc, char **argv)
{
	char *argv_out[argc];
	int argc_out = 0;

	argv_out[argc_out++] = argv[0];

	/* disable generation of error messages on encountering unknown
	 * options */
	opterr = 0;

	while (1) {
		int option_idx = 0, c;
		static const struct option long_options[] = {
			/* FIXME: all those are generic Osmocom app options */
			{ "help", 0, 0, 'h' },
			{ "debug", 1, 0, 'd' },
			{ "daemonize", 0, 0, 'D' },
			{ "config-file", 1, 0, 'c' },
			{ "disable-color", 0, 0, 's' },
			{ "timestamp", 0, 0, 'T' },
			{ "version", 0, 0, 'V' },
			{ "log-level", 1, 0, 'e' },
			/* FIXME: generic BTS app options */
			{ "gsmtap-ip", 1, 0, 'i' },
			{ "trx-num", 1, 0, 't' },
			{ "realtime", 1, 0, 'r' },
			{ 0, 0, 0, 0 }
		};

		c = getopt_long(argc, argv, "-hc:d:Dc:sTVe:i:t:r:",
				long_options, &option_idx);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_help();
			exit(0);
			break;
		case 's':
			log_set_use_color(osmo_stderr_target, 0);
			break;
		case 'd':
			log_parse_category_mask(osmo_stderr_target, optarg);
			break;
		case 'D':
			daemonize = 1;
			break;
		case 'c':
			config_file = optarg;
			break;
		case 'T':
			log_set_print_timestamp(osmo_stderr_target, 1);
			break;
		case 'V':
			print_version(1);
			exit(0);
			break;
		case 'e':
			log_set_log_level(osmo_stderr_target, atoi(optarg));
			break;
		case 'r':
			rt_prio = atoi(optarg);
			break;
		case 'i':
			gsmtap_ip = optarg;
			break;
		case 't':
			trx_num = atoi(optarg);
			if (trx_num < 1)
				trx_num = 1;
			break;
		case '?':
		case 1:
			/* prepare argv[] for bts_model */
			argv_out[argc_out++] = argv[optind-1];
			break;
		default:
			break;
		}
	}

	/* re-set opt-ind for new parsig round */
	optind = 1;
	/* enable error-checking for the following getopt call */
	opterr = 1;
	if (bts_model_handle_options(argc_out, argv_out)) {
		print_help();
		exit(1);
	}
}
Пример #9
0
/*
 * Read all reloadable configuration directives
 */
static void config_reload(int reload) {
    Cfg *cfg;
    CfgGroup *grp;
    List *groups;
    long map_url_max;
    Octstr *s;
    long i;
    long new_value;
    int new_bool;
    Octstr *http_proxy_host;
    Octstr *http_interface_name;
    long http_proxy_port;
    int http_proxy_ssl = 0;
    List *http_proxy_exceptions;
    Octstr *http_proxy_username;
    Octstr *http_proxy_password;
    Octstr *http_proxy_exceptions_regex;
    int warn_map_url = 0;

    /* XXX TO-DO: if(reload) implement wapbox.suspend/mutex.lock */
    
    if (reload)
        debug("config_reload", 0, "Reloading configuration");

    /* 
     * NOTE: we could lstat config file and only reload if it was modified, 
     * but as we have a include directive, we don't know every file's
     * timestamp at this point
     */

    cfg = cfg_create(config_filename);

    if (cfg_read(cfg) == -1) {
        warning(0, "Couldn't %sload configuration from `%s'.", 
                   (reload ? "re" : ""), octstr_get_cstr(config_filename));
        return;
    }

    grp = cfg_get_single_group(cfg, octstr_imm("core"));

    http_proxy_host = cfg_get(grp, octstr_imm("http-proxy-host"));
    http_proxy_port =  -1;
    cfg_get_integer(&http_proxy_port, grp, octstr_imm("http-proxy-port"));
#ifdef HAVE_LIBSSL
    cfg_get_bool(&http_proxy_ssl, grp, octstr_imm("http-proxy-ssl"));
#endif /* HAVE_LIBSSL */
    http_proxy_username = cfg_get(grp, octstr_imm("http-proxy-username"));
    http_proxy_password = cfg_get(grp, octstr_imm("http-proxy-password"));
    http_proxy_exceptions = cfg_get_list(grp, octstr_imm("http-proxy-exceptions"));
    http_proxy_exceptions_regex = cfg_get(grp, octstr_imm("http-proxy-exceptions-regex"));
    if (http_proxy_host != NULL && http_proxy_port > 0) {
        http_use_proxy(http_proxy_host, http_proxy_port, http_proxy_ssl,
                       http_proxy_exceptions, http_proxy_username, 
                       http_proxy_password, http_proxy_exceptions_regex);
    }
    octstr_destroy(http_proxy_host);
    octstr_destroy(http_proxy_username);
    octstr_destroy(http_proxy_password);
    octstr_destroy(http_proxy_exceptions_regex);
    gwlist_destroy(http_proxy_exceptions, octstr_destroy_item);

    grp = cfg_get_single_group(cfg, octstr_imm("wapbox"));
    if (grp == NULL) {
        warning(0, "No 'wapbox' group in configuration.");
        return;
    }
    
    if (cfg_get_integer(&new_value, grp, octstr_imm("log-level")) != -1) {
        reload_int(reload, octstr_imm("log level"), &logfilelevel, &new_value);
        logfilelevel = new_value;
        log_set_log_level(new_value);
    }

    /* Configure interface name for http requests */
    http_interface_name = cfg_get(grp, octstr_imm("http-interface-name"));
    if (http_interface_name != NULL) {
        http_set_interface(http_interface_name);
        octstr_destroy(http_interface_name);
    }

    /* 
     * users may define 'smart-errors' to have WML decks returned with
     * error information instead of signaling using the HTTP reply codes
     */
    cfg_get_bool(&new_bool, grp, octstr_imm("smart-errors"));
    reload_bool(reload, octstr_imm("smart error messaging"), &wsp_smart_errors, &new_bool);

    /* decide if our XML parser within WML compiler is strict or relaxed */
    cfg_get_bool(&new_bool, grp, octstr_imm("wml-strict"));
    reload_bool(reload, octstr_imm("XML within WML has to be strict"), 
                &wml_xml_strict, &new_bool);
    if (!wml_xml_strict)
        warning(0, "'wml-strict' config directive has been set to no, "
                   "this may make you vulnerable against XML bogus input.");

    if (cfg_get_bool(&new_bool, grp, octstr_imm("concatenation")) == 1)
        reload_bool(reload, octstr_imm("concatenation"), &concatenation, &new_bool);
    else
        concatenation = 1;

    if (cfg_get_integer(&new_value, grp, octstr_imm("max-messages")) != -1) {
        max_messages = new_value;
        reload_int(reload, octstr_imm("max messages"), &max_messages, &new_value);
    }

    /* configure URL mappings */
    map_url_max = -1;
    cfg_get_integer(&map_url_max, grp, octstr_imm("map-url-max"));
    if (map_url_max > 0)
        warn_map_url = 1;

    if (reload) { /* clear old map */
        wap_map_destroy();
        wap_map_user_destroy();
    }
	
    if ((device_home = cfg_get(grp, octstr_imm("device-home"))) != NULL) {
        wap_map_url_config_device_home(octstr_get_cstr(device_home));
    }
    if ((s = cfg_get(grp, octstr_imm("map-url"))) != NULL) {
        warn_map_url = 1;
        wap_map_url_config(octstr_get_cstr(s));
        octstr_destroy(s);
    }
    debug("wap", 0, "map_url_max = %ld", map_url_max);

    for (i = 0; i <= map_url_max; i++) {
        Octstr *name;
        name = octstr_format("map-url-%d", i);
        if ((s = cfg_get(grp, name)) != NULL)
            wap_map_url_config(octstr_get_cstr(s));
        octstr_destroy(name);
    }

    /* warn the user that he/she should use the new wap-url-map groups */
    if (warn_map_url)
        warning(0, "'map-url' config directive and related are deprecated, "
                   "please use wap-url-map group");

    /* configure wap-url-map */
    groups = cfg_get_multi_group(cfg, octstr_imm("wap-url-map"));
    while (groups && (grp = gwlist_extract_first(groups)) != NULL) {
        Octstr *name, *url, *map_url, *send_msisdn_query;
        Octstr *send_msisdn_header, *send_msisdn_format;
        int accept_cookies;

        name = cfg_get(grp, octstr_imm("name"));
        url = cfg_get(grp, octstr_imm("url"));
        map_url = cfg_get(grp, octstr_imm("map-url"));
        send_msisdn_query = cfg_get(grp, octstr_imm("send-msisdn-query"));
        send_msisdn_header = cfg_get(grp, octstr_imm("send-msisdn-header"));
        send_msisdn_format = cfg_get(grp, octstr_imm("send-msisdn-format"));
        accept_cookies = -1;
        cfg_get_bool(&accept_cookies, grp, octstr_imm("accept-cookies"));

        wap_map_add_url(name, url, map_url, send_msisdn_query, send_msisdn_header,
                        send_msisdn_format, accept_cookies);

        info(0, "Added wap-url-map <%s> with url <%s>, map-url <%s>, "
                "send-msisdn-query <%s>, send-msisdn-header <%s>, "
                "send-msisdn-format <%s>, accept-cookies <%s>", 
             octstr_get_cstr(name), octstr_get_cstr(url), 
             octstr_get_cstr(map_url), octstr_get_cstr(send_msisdn_query), 
             octstr_get_cstr(send_msisdn_header), 
             octstr_get_cstr(send_msisdn_format), (accept_cookies ? "yes" : "no"));
    }
    gwlist_destroy(groups, NULL);

    /* configure wap-user-map */
    groups = cfg_get_multi_group(cfg, octstr_imm("wap-user-map"));
    while (groups && (grp = gwlist_extract_first(groups)) != NULL) {
        Octstr *name, *user, *pass, *msisdn;

        name = cfg_get(grp, octstr_imm("name"));
        user = cfg_get(grp, octstr_imm("user"));
        pass = cfg_get(grp, octstr_imm("pass"));
        msisdn = cfg_get(grp, octstr_imm("msisdn"));
           
        wap_map_add_user(name, user, pass, msisdn);

        info(0,"Added wap-user-map <%s> with credentials <%s:%s> "
               "and MSISDN <%s>", octstr_get_cstr(name),
             octstr_get_cstr(user), octstr_get_cstr(pass),
             octstr_get_cstr(msisdn));
    }
    gwlist_destroy(groups, NULL);

    cfg_destroy(cfg);
    /* XXX TO-DO: if(reload) implement wapbox.resume/mutex.unlock */
}
Пример #10
0
int main(int argc, char **argv)
{
	int quit = 0;
	int rc;
	char const * home;
	size_t len;
	const char osmocomcfg[] = ".osmocom/bb/mobile.cfg";
	char *config_file = NULL;

	printf("%s\n", openbsc_copyright);

	srand(time(NULL));

	INIT_LLIST_HEAD(&ms_list);
	log_init(&log_info, NULL);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);
	log_set_all_filter(stderr_target, 1);

	l23_ctx = talloc_named_const(NULL, 1, "layer2 context");
	msgb_set_talloc_ctx(l23_ctx);

	handle_options(argc, argv);

	if (!debug_set)
		log_parse_category_mask(stderr_target, debug_default);
	log_set_log_level(stderr_target, LOGL_DEBUG);

	if (gsmtap_ip) {
		gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
		if (!gsmtap_inst) {
			fprintf(stderr, "Failed during gsmtap_init()\n");
			exit(1);
		}
		gsmtap_source_add_sink(gsmtap_inst);
	}

	home = getenv("HOME");
	if (home != NULL) {
		len = strlen(home) + 1 + sizeof(osmocomcfg);
		config_file = talloc_size(l23_ctx, len);
		if (config_file != NULL)
			snprintf(config_file, len, "%s/%s", home, osmocomcfg);
	}
	/* save the config file directory name */
	config_dir = talloc_strdup(l23_ctx, config_file);
	config_dir = dirname(config_dir);

	if (use_mncc_sock)
		rc = l23_app_init(mncc_recv_socket, config_file, vty_port);
	else
		rc = l23_app_init(NULL, config_file, vty_port);
	if (rc)
		exit(rc);

	signal(SIGINT, sighandler);
	signal(SIGHUP, sighandler);
	signal(SIGTERM, sighandler);
	signal(SIGPIPE, sighandler);
	signal(SIGABRT, sighandler);
	signal(SIGUSR1, sighandler);
	signal(SIGUSR2, sighandler);

	if (daemonize) {
		printf("Running as daemon\n");
		rc = osmo_daemonize();
		if (rc)
			fprintf(stderr, "Failed to run as daemon\n");
	}

	while (1) {
		l23_app_work(&quit);
		if (quit && llist_empty(&ms_list))
			break;
		osmo_select_main(0);
	}

	l23_app_exit();

	talloc_free(config_file);
	talloc_free(config_dir);
	talloc_report_full(l23_ctx, stderr);

	return 0;
}