18dbcf02cSchristos /*
28dbcf02cSchristos  * WPA Supplicant / main() function for UNIX like OSes and MinGW
336d97821Schristos  * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos  *
562a52023Schristos  * This software may be distributed under the terms of the BSD license.
662a52023Schristos  * See README for more details.
78dbcf02cSchristos  */
88dbcf02cSchristos 
98dbcf02cSchristos #include "includes.h"
108dbcf02cSchristos #ifdef __linux__
118dbcf02cSchristos #include <fcntl.h>
128dbcf02cSchristos #endif /* __linux__ */
138dbcf02cSchristos 
148dbcf02cSchristos #include "common.h"
158d355d6fSchristos #include "fst/fst.h"
168dbcf02cSchristos #include "wpa_supplicant_i.h"
178dbcf02cSchristos #include "driver_i.h"
1836d97821Schristos #include "p2p_supplicant.h"
198dbcf02cSchristos 
208dbcf02cSchristos 
usage(void)218dbcf02cSchristos static void usage(void)
228dbcf02cSchristos {
238dbcf02cSchristos 	int i;
248dbcf02cSchristos 	printf("%s\n\n%s\n"
258dbcf02cSchristos 	       "usage:\n"
2636d97821Schristos 	       "  wpa_supplicant [-BddhKLqq"
2736d97821Schristos #ifdef CONFIG_DEBUG_SYSLOG
2836d97821Schristos 	       "s"
2936d97821Schristos #endif /* CONFIG_DEBUG_SYSLOG */
3036d97821Schristos 	       "t"
31*0dddab58Schristos #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
3236d97821Schristos 	       "u"
33*0dddab58Schristos #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
3436d97821Schristos 	       "vW] [-P<pid file>] "
358dbcf02cSchristos 	       "[-g<global ctrl>] \\\n"
3636d97821Schristos 	       "        [-G<group>] \\\n"
378dbcf02cSchristos 	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
388dbcf02cSchristos 	       "[-p<driver_param>] \\\n"
3936d97821Schristos 	       "        [-b<br_ifname>] [-e<entropy file>]"
4036d97821Schristos #ifdef CONFIG_DEBUG_FILE
4136d97821Schristos 	       " [-f<debug file>]"
4236d97821Schristos #endif /* CONFIG_DEBUG_FILE */
4342669be3Schristos 	       " \\\n"
448dbcf02cSchristos 	       "        [-o<override driver>] [-O<override ctrl>] \\\n"
458dbcf02cSchristos 	       "        [-N -i<ifname> -c<conf> [-C<ctrl>] "
468dbcf02cSchristos 	       "[-D<driver>] \\\n"
4736d97821Schristos #ifdef CONFIG_P2P
4836d97821Schristos 	       "        [-m<P2P Device config file>] \\\n"
4936d97821Schristos #endif /* CONFIG_P2P */
5036d97821Schristos 	       "        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] "
5136d97821Schristos 	       "...]\n"
528dbcf02cSchristos 	       "\n"
538dbcf02cSchristos 	       "drivers:\n",
548dbcf02cSchristos 	       wpa_supplicant_version, wpa_supplicant_license);
558dbcf02cSchristos 
568dbcf02cSchristos 	for (i = 0; wpa_drivers[i]; i++) {
578dbcf02cSchristos 		printf("  %s = %s\n",
588dbcf02cSchristos 		       wpa_drivers[i]->name,
598dbcf02cSchristos 		       wpa_drivers[i]->desc);
608dbcf02cSchristos 	}
618dbcf02cSchristos 
628dbcf02cSchristos #ifndef CONFIG_NO_STDOUT_DEBUG
638dbcf02cSchristos 	printf("options:\n"
648dbcf02cSchristos 	       "  -b = optional bridge interface name\n"
658dbcf02cSchristos 	       "  -B = run daemon in the background\n"
668dbcf02cSchristos 	       "  -c = Configuration file\n"
678dbcf02cSchristos 	       "  -C = ctrl_interface parameter (only used if -c is not)\n"
688dbcf02cSchristos 	       "  -d = increase debugging verbosity (-dd even more)\n"
6942669be3Schristos 	       "  -D = driver name (can be multiple drivers: nl80211,wext)\n"
7066edc40fSroy 	       "  -e = entropy file\n"
718dbcf02cSchristos #ifdef CONFIG_DEBUG_FILE
7266edc40fSroy 	       "  -f = log output to debug file instead of stdout\n"
738dbcf02cSchristos #endif /* CONFIG_DEBUG_FILE */
7466edc40fSroy 	       "  -g = global ctrl_interface\n"
7536d97821Schristos 	       "  -G = global ctrl_interface group\n"
768dbcf02cSchristos 	       "  -h = show this help text\n"
7766edc40fSroy 	       "  -i = interface name\n"
7866edc40fSroy 	       "  -I = additional configuration file\n"
7966edc40fSroy 	       "  -K = include keys (passwords, etc.) in debug output\n"
8062a52023Schristos 	       "  -L = show license (BSD)\n"
8166edc40fSroy #ifdef CONFIG_P2P
8266edc40fSroy 	       "  -m = Configuration file for the P2P Device interface\n"
8366edc40fSroy #endif /* CONFIG_P2P */
846855b8beSroy #ifdef CONFIG_MATCH_IFACE
856855b8beSroy 	       "  -M = start describing new matching interface\n"
866855b8beSroy #endif /* CONFIG_MATCH_IFACE */
8766edc40fSroy 	       "  -N = start describing new interface\n"
888dbcf02cSchristos 	       "  -o = override driver parameter for new interfaces\n"
898dbcf02cSchristos 	       "  -O = override ctrl_interface parameter for new interfaces\n"
908dbcf02cSchristos 	       "  -p = driver parameters\n"
918dbcf02cSchristos 	       "  -P = PID file\n"
9266edc40fSroy 	       "  -q = decrease debugging verbosity (-qq even less)\n"
9366edc40fSroy #ifdef CONFIG_DEBUG_SYSLOG
9466edc40fSroy 	       "  -s = log output to syslog instead of stdout\n"
9566edc40fSroy #endif /* CONFIG_DEBUG_SYSLOG */
968d355d6fSchristos 	       "  -t = include timestamp in debug messages\n"
9766edc40fSroy #ifdef CONFIG_DEBUG_LINUX_TRACING
9866edc40fSroy 	       "  -T = record to Linux tracing in addition to logging\n"
9966edc40fSroy 	       "       (records all messages regardless of debug verbosity)\n"
10066edc40fSroy #endif /* CONFIG_DEBUG_LINUX_TRACING */
101*0dddab58Schristos #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
10266edc40fSroy 	       "  -u = enable DBus control interface\n"
103*0dddab58Schristos #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
10466edc40fSroy 	       "  -v = show version\n"
1058d355d6fSchristos 	       "  -W = wait for a control interface monitor before starting\n");
1068dbcf02cSchristos 
1078dbcf02cSchristos 	printf("example:\n"
1088dbcf02cSchristos 	       "  wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n",
10936d97821Schristos 	       wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211");
1108dbcf02cSchristos #endif /* CONFIG_NO_STDOUT_DEBUG */
1118dbcf02cSchristos }
1128dbcf02cSchristos 
1138dbcf02cSchristos 
license(void)1148dbcf02cSchristos static void license(void)
1158dbcf02cSchristos {
1168dbcf02cSchristos #ifndef CONFIG_NO_STDOUT_DEBUG
1178dbcf02cSchristos 	printf("%s\n\n%s%s%s%s%s\n",
1188dbcf02cSchristos 	       wpa_supplicant_version,
1198dbcf02cSchristos 	       wpa_supplicant_full_license1,
1208dbcf02cSchristos 	       wpa_supplicant_full_license2,
1218dbcf02cSchristos 	       wpa_supplicant_full_license3,
1228dbcf02cSchristos 	       wpa_supplicant_full_license4,
1238dbcf02cSchristos 	       wpa_supplicant_full_license5);
1248dbcf02cSchristos #endif /* CONFIG_NO_STDOUT_DEBUG */
1258dbcf02cSchristos }
1268dbcf02cSchristos 
1278dbcf02cSchristos 
wpa_supplicant_fd_workaround(int start)12862a52023Schristos static void wpa_supplicant_fd_workaround(int start)
1298dbcf02cSchristos {
1308dbcf02cSchristos #ifdef __linux__
13162a52023Schristos 	static int fd[3] = { -1, -1, -1 };
13262a52023Schristos 	int i;
1338dbcf02cSchristos 	/* When started from pcmcia-cs scripts, wpa_supplicant might start with
1348dbcf02cSchristos 	 * fd 0, 1, and 2 closed. This will cause some issues because many
1358dbcf02cSchristos 	 * places in wpa_supplicant are still printing out to stdout. As a
1368dbcf02cSchristos 	 * workaround, make sure that fd's 0, 1, and 2 are not used for other
1378dbcf02cSchristos 	 * sockets. */
13862a52023Schristos 	if (start) {
1398dbcf02cSchristos 		for (i = 0; i < 3; i++) {
14062a52023Schristos 			fd[i] = open("/dev/null", O_RDWR);
14162a52023Schristos 			if (fd[i] > 2) {
14262a52023Schristos 				close(fd[i]);
14362a52023Schristos 				fd[i] = -1;
1448dbcf02cSchristos 				break;
1458dbcf02cSchristos 			}
1468dbcf02cSchristos 		}
14762a52023Schristos 	} else {
14862a52023Schristos 		for (i = 0; i < 3; i++) {
14962a52023Schristos 			if (fd[i] >= 0) {
15062a52023Schristos 				close(fd[i]);
15162a52023Schristos 				fd[i] = -1;
15262a52023Schristos 			}
15362a52023Schristos 		}
15462a52023Schristos 	}
1558dbcf02cSchristos #endif /* __linux__ */
1568dbcf02cSchristos }
1578dbcf02cSchristos 
1588dbcf02cSchristos 
1596855b8beSroy #ifdef CONFIG_MATCH_IFACE
wpa_supplicant_init_match(struct wpa_global * global)1606855b8beSroy static int wpa_supplicant_init_match(struct wpa_global *global)
1616855b8beSroy {
1626855b8beSroy 	/*
1636855b8beSroy 	 * The assumption is that the first driver is the primary driver and
1646855b8beSroy 	 * will handle the arrival / departure of interfaces.
1656855b8beSroy 	 */
1666855b8beSroy 	if (wpa_drivers[0]->global_init && !global->drv_priv[0]) {
1676855b8beSroy 		global->drv_priv[0] = wpa_drivers[0]->global_init(global);
1686855b8beSroy 		if (!global->drv_priv[0]) {
1696855b8beSroy 			wpa_printf(MSG_ERROR,
1706855b8beSroy 				   "Failed to initialize driver '%s'",
1716855b8beSroy 				   wpa_drivers[0]->name);
1726855b8beSroy 			return -1;
1736855b8beSroy 		}
1746855b8beSroy 	}
1756855b8beSroy 
1766855b8beSroy 	return 0;
1776855b8beSroy }
1786855b8beSroy #endif /* CONFIG_MATCH_IFACE */
1796855b8beSroy 
1806855b8beSroy 
main(int argc,char * argv[])1818dbcf02cSchristos int main(int argc, char *argv[])
1828dbcf02cSchristos {
1838dbcf02cSchristos 	int c, i;
1848dbcf02cSchristos 	struct wpa_interface *ifaces, *iface;
1858dbcf02cSchristos 	int iface_count, exitcode = -1;
1868dbcf02cSchristos 	struct wpa_params params;
1878dbcf02cSchristos 	struct wpa_global *global;
1888dbcf02cSchristos 
1898dbcf02cSchristos 	if (os_program_init())
1908dbcf02cSchristos 		return -1;
1918dbcf02cSchristos 
1928dbcf02cSchristos 	os_memset(&params, 0, sizeof(params));
1938dbcf02cSchristos 	params.wpa_debug_level = MSG_INFO;
1948dbcf02cSchristos 
1958dbcf02cSchristos 	iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
1968dbcf02cSchristos 	if (ifaces == NULL)
1978dbcf02cSchristos 		return -1;
1988dbcf02cSchristos 	iface_count = 1;
1998dbcf02cSchristos 
20062a52023Schristos 	wpa_supplicant_fd_workaround(1);
2018dbcf02cSchristos 
2028dbcf02cSchristos 	for (;;) {
20362a52023Schristos 		c = getopt(argc, argv,
2046855b8beSroy 			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW");
2058dbcf02cSchristos 		if (c < 0)
2068dbcf02cSchristos 			break;
2078dbcf02cSchristos 		switch (c) {
2088dbcf02cSchristos 		case 'b':
2098dbcf02cSchristos 			iface->bridge_ifname = optarg;
2108dbcf02cSchristos 			break;
2118dbcf02cSchristos 		case 'B':
2128dbcf02cSchristos 			params.daemonize++;
2138dbcf02cSchristos 			break;
2148dbcf02cSchristos 		case 'c':
2158dbcf02cSchristos 			iface->confname = optarg;
2168dbcf02cSchristos 			break;
2178dbcf02cSchristos 		case 'C':
2188dbcf02cSchristos 			iface->ctrl_interface = optarg;
2198dbcf02cSchristos 			break;
2208dbcf02cSchristos 		case 'D':
2218dbcf02cSchristos 			iface->driver = optarg;
2228dbcf02cSchristos 			break;
2238dbcf02cSchristos 		case 'd':
2248dbcf02cSchristos #ifdef CONFIG_NO_STDOUT_DEBUG
2258dbcf02cSchristos 			printf("Debugging disabled with "
2268dbcf02cSchristos 			       "CONFIG_NO_STDOUT_DEBUG=y build time "
2278dbcf02cSchristos 			       "option.\n");
2288dbcf02cSchristos 			goto out;
2298dbcf02cSchristos #else /* CONFIG_NO_STDOUT_DEBUG */
2308dbcf02cSchristos 			params.wpa_debug_level--;
2318dbcf02cSchristos 			break;
2328dbcf02cSchristos #endif /* CONFIG_NO_STDOUT_DEBUG */
23342669be3Schristos 		case 'e':
23442669be3Schristos 			params.entropy_file = optarg;
23542669be3Schristos 			break;
2368dbcf02cSchristos #ifdef CONFIG_DEBUG_FILE
2378dbcf02cSchristos 		case 'f':
2388dbcf02cSchristos 			params.wpa_debug_file_path = optarg;
2398dbcf02cSchristos 			break;
2408dbcf02cSchristos #endif /* CONFIG_DEBUG_FILE */
2418dbcf02cSchristos 		case 'g':
2428dbcf02cSchristos 			params.ctrl_interface = optarg;
2438dbcf02cSchristos 			break;
24436d97821Schristos 		case 'G':
24536d97821Schristos 			params.ctrl_interface_group = optarg;
24636d97821Schristos 			break;
2478dbcf02cSchristos 		case 'h':
2488dbcf02cSchristos 			usage();
2498dbcf02cSchristos 			exitcode = 0;
2508dbcf02cSchristos 			goto out;
2518dbcf02cSchristos 		case 'i':
2528dbcf02cSchristos 			iface->ifname = optarg;
2538dbcf02cSchristos 			break;
25436d97821Schristos 		case 'I':
25536d97821Schristos 			iface->confanother = optarg;
25636d97821Schristos 			break;
2578dbcf02cSchristos 		case 'K':
2588dbcf02cSchristos 			params.wpa_debug_show_keys++;
2598dbcf02cSchristos 			break;
2608dbcf02cSchristos 		case 'L':
2618dbcf02cSchristos 			license();
2628dbcf02cSchristos 			exitcode = 0;
2638dbcf02cSchristos 			goto out;
26436d97821Schristos #ifdef CONFIG_P2P
26536d97821Schristos 		case 'm':
2668d355d6fSchristos 			params.conf_p2p_dev = optarg;
26736d97821Schristos 			break;
26836d97821Schristos #endif /* CONFIG_P2P */
2698dbcf02cSchristos 		case 'o':
2708dbcf02cSchristos 			params.override_driver = optarg;
2718dbcf02cSchristos 			break;
2728dbcf02cSchristos 		case 'O':
2738dbcf02cSchristos 			params.override_ctrl_interface = optarg;
2748dbcf02cSchristos 			break;
2758dbcf02cSchristos 		case 'p':
2768dbcf02cSchristos 			iface->driver_param = optarg;
2778dbcf02cSchristos 			break;
2788dbcf02cSchristos 		case 'P':
2798dbcf02cSchristos 			os_free(params.pid_file);
2808dbcf02cSchristos 			params.pid_file = os_rel2abs_path(optarg);
2818dbcf02cSchristos 			break;
2828dbcf02cSchristos 		case 'q':
2838dbcf02cSchristos 			params.wpa_debug_level++;
2848dbcf02cSchristos 			break;
2858dbcf02cSchristos #ifdef CONFIG_DEBUG_SYSLOG
2868dbcf02cSchristos 		case 's':
2878dbcf02cSchristos 			params.wpa_debug_syslog++;
2888dbcf02cSchristos 			break;
2898dbcf02cSchristos #endif /* CONFIG_DEBUG_SYSLOG */
29062a52023Schristos #ifdef CONFIG_DEBUG_LINUX_TRACING
29162a52023Schristos 		case 'T':
29262a52023Schristos 			params.wpa_debug_tracing++;
29362a52023Schristos 			break;
29462a52023Schristos #endif /* CONFIG_DEBUG_LINUX_TRACING */
2958dbcf02cSchristos 		case 't':
2968dbcf02cSchristos 			params.wpa_debug_timestamp++;
2978dbcf02cSchristos 			break;
298*0dddab58Schristos #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
2998dbcf02cSchristos 		case 'u':
3008dbcf02cSchristos 			params.dbus_ctrl_interface = 1;
3018dbcf02cSchristos 			break;
302*0dddab58Schristos #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
3038dbcf02cSchristos 		case 'v':
3048dbcf02cSchristos 			printf("%s\n", wpa_supplicant_version);
3058dbcf02cSchristos 			exitcode = 0;
3068dbcf02cSchristos 			goto out;
3078dbcf02cSchristos 		case 'W':
3088dbcf02cSchristos 			params.wait_for_monitor++;
3098dbcf02cSchristos 			break;
3106855b8beSroy #ifdef CONFIG_MATCH_IFACE
3116855b8beSroy 		case 'M':
3126855b8beSroy 			params.match_iface_count++;
3136855b8beSroy 			iface = os_realloc_array(params.match_ifaces,
3146855b8beSroy 						 params.match_iface_count,
3156855b8beSroy 						 sizeof(struct wpa_interface));
3166855b8beSroy 			if (!iface)
3176855b8beSroy 				goto out;
3186855b8beSroy 			params.match_ifaces = iface;
3196855b8beSroy 			iface = &params.match_ifaces[params.match_iface_count -
3206855b8beSroy 						     1];
3216855b8beSroy 			os_memset(iface, 0, sizeof(*iface));
3226855b8beSroy 			break;
3236855b8beSroy #endif /* CONFIG_MATCH_IFACE */
3248dbcf02cSchristos 		case 'N':
3258dbcf02cSchristos 			iface_count++;
32662a52023Schristos 			iface = os_realloc_array(ifaces, iface_count,
3278dbcf02cSchristos 						 sizeof(struct wpa_interface));
3288dbcf02cSchristos 			if (iface == NULL)
3298dbcf02cSchristos 				goto out;
3308dbcf02cSchristos 			ifaces = iface;
3318dbcf02cSchristos 			iface = &ifaces[iface_count - 1];
3328dbcf02cSchristos 			os_memset(iface, 0, sizeof(*iface));
3338dbcf02cSchristos 			break;
3348dbcf02cSchristos 		default:
3358dbcf02cSchristos 			usage();
3368dbcf02cSchristos 			exitcode = 0;
3378dbcf02cSchristos 			goto out;
3388dbcf02cSchristos 		}
3398dbcf02cSchristos 	}
3408dbcf02cSchristos 
3418dbcf02cSchristos 	exitcode = 0;
3428dbcf02cSchristos 	global = wpa_supplicant_init(&params);
3438dbcf02cSchristos 	if (global == NULL) {
3448dbcf02cSchristos 		wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
3458dbcf02cSchristos 		exitcode = -1;
3468dbcf02cSchristos 		goto out;
34762a52023Schristos 	} else {
34862a52023Schristos 		wpa_printf(MSG_INFO, "Successfully initialized "
34962a52023Schristos 			   "wpa_supplicant");
3508dbcf02cSchristos 	}
3518dbcf02cSchristos 
3528d355d6fSchristos 	if (fst_global_init()) {
3538d355d6fSchristos 		wpa_printf(MSG_ERROR, "Failed to initialize FST");
3548d355d6fSchristos 		exitcode = -1;
3558d355d6fSchristos 		goto out;
3568d355d6fSchristos 	}
3578d355d6fSchristos 
3588d355d6fSchristos #if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE)
3598d355d6fSchristos 	if (!fst_global_add_ctrl(fst_ctrl_cli))
3608d355d6fSchristos 		wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl");
3618d355d6fSchristos #endif
3628d355d6fSchristos 
3638dbcf02cSchristos 	for (i = 0; exitcode == 0 && i < iface_count; i++) {
36436d97821Schristos 		struct wpa_supplicant *wpa_s;
36536d97821Schristos 
3668dbcf02cSchristos 		if ((ifaces[i].confname == NULL &&
3678dbcf02cSchristos 		     ifaces[i].ctrl_interface == NULL) ||
3688dbcf02cSchristos 		    ifaces[i].ifname == NULL) {
3698dbcf02cSchristos 			if (iface_count == 1 && (params.ctrl_interface ||
3706855b8beSroy #ifdef CONFIG_MATCH_IFACE
3716855b8beSroy 						 params.match_iface_count ||
3726855b8beSroy #endif /* CONFIG_MATCH_IFACE */
3738dbcf02cSchristos 						 params.dbus_ctrl_interface))
3748dbcf02cSchristos 				break;
3758dbcf02cSchristos 			usage();
3768dbcf02cSchristos 			exitcode = -1;
3778dbcf02cSchristos 			break;
3788dbcf02cSchristos 		}
3799a53cbbeSchristos 		wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
38036d97821Schristos 		if (wpa_s == NULL) {
3818dbcf02cSchristos 			exitcode = -1;
38236d97821Schristos 			break;
38336d97821Schristos 		}
3848dbcf02cSchristos 	}
3858dbcf02cSchristos 
3866855b8beSroy #ifdef CONFIG_MATCH_IFACE
3876855b8beSroy 	if (exitcode == 0)
3886855b8beSroy 		exitcode = wpa_supplicant_init_match(global);
3896855b8beSroy #endif /* CONFIG_MATCH_IFACE */
3906855b8beSroy 
3918dbcf02cSchristos 	if (exitcode == 0)
3928dbcf02cSchristos 		exitcode = wpa_supplicant_run(global);
3938dbcf02cSchristos 
3948dbcf02cSchristos 	wpa_supplicant_deinit(global);
3958dbcf02cSchristos 
3968d355d6fSchristos 	fst_global_deinit();
3978d355d6fSchristos 
3988dbcf02cSchristos out:
39962a52023Schristos 	wpa_supplicant_fd_workaround(0);
4008dbcf02cSchristos 	os_free(ifaces);
4016855b8beSroy #ifdef CONFIG_MATCH_IFACE
4026855b8beSroy 	os_free(params.match_ifaces);
4036855b8beSroy #endif /* CONFIG_MATCH_IFACE */
4048dbcf02cSchristos 	os_free(params.pid_file);
4058dbcf02cSchristos 
4068dbcf02cSchristos 	os_program_deinit();
4078dbcf02cSchristos 
4088dbcf02cSchristos 	return exitcode;
4098dbcf02cSchristos }
410