Exemple #1
0
int set_resolution(int init) {
	int width, height, fs, ms;
	option_t *option = config_get_option("resolution");
	config_resolution_t *res = option->selected->data;

	option = config_get_option("full_screen");
	fs = option->selected->index;

	option = config_get_option("multisampling");

	ms = option->selected->index * 2;

	if (res) {
		width = res->w;
		height = res->h;
	} else {
		/* Custom */
		option = config_get_option("custom_resolution_width");
		width = option->value;
		option = config_get_option("custom_resolution_height");
		height = option->value;
	}

	if (init)
		return ui->create_window(width, height, fs, ms);
	else
		return ui->resize(width, height, fs, ms);
}
static int dialog_title_music_vol(gg_widget_t *widget, gg_widget_t *emitter, void *data, void *extra_data) {
	option_t *option = config_get_option("music_volume");
	option_select_value_by_index(option, gg_option_get_selected(GG_OPTION(widget)));

	audio_set_music_volume(option->selected->index);

	return 1;
}
static int dialog_close_cb(gg_widget_t *widget, gg_widget_t *emitter, void *data, void *extra_data) {
	option_t *option = config_get_option("first_engine");
	free(option->string);
	option->string = strdup(gg_entry_get_text(GG_ENTRY(entry)));
	config_save();
	gg_dialog_close();
	return 1;
}
Exemple #4
0
static
int say_welcome(int sock_fd) {
	const char* welcome = config_get_option("welcomeline");

	if (config_get_option("welcomeline")) {
		char* welcmsg;

		welcmsg = prependcode(welcome, 220);
		enough_mem(welcmsg);

		jlog(9, "Saying this text as welcomeline: %s", welcmsg);
		say(sock_fd, welcmsg);
		free(welcmsg);
	} else {
		say(sock_fd, "220 Joe FTP Proxy Server/Gateway (v"JFTPGW_VERSION") ready\r\n");
	}
	return 0;
}
Exemple #5
0
const char * config_get_value (void * session, const char * valuename) {
   XML * mark = config_get_option (session, valuename);
   if (mark) return (xml_attrval (mark, "value"));

   if (!strcmp (valuename, "pdrep.localxml.directory")) return PROCDEF_DIRECTORY;
   if (!strcmp (valuename, "dsrep.localxml.directory")) return DATASHEET_DIRECTORY;
   if (!strcmp (valuename, "user.localxml.directory")) return USER_DIRECTORY;
   if (!strcmp (valuename, "group.localxml.directory")) return GROUP_DIRECTORY;
   if (!strcmp (valuename, "taskindex.odbc.?.conn")) return ODBC_CONNECTION;
   return "";
}
Exemple #6
0
static int mod_http_chroot(void)
{
    calipso_config_t *config = calipso_get_config();

    /* Check wether chroot()-ing is required, chroot is default behaviour */
    const char *chrootenable = config_get_option(config, "chroot", NULL);
	const char *chrootpath = config_get_option(config, "chrootpath", NULL);

    if (chrootenable == NULL) {
        if ( calipso_get_uid() )
            printf("Chroot() must be disabled as non privileged user.");
        if (chrootpath == NULL)
            printf("Chroot() directive enabled, but no ChrootPath() set.");
        if (chroot(chrootpath) < 0)
            printf("chroot() call failure in %s.", __func__);
        if (chdir("/") < 0)
            printf("chdir() call failure in %s.", __func__);
    }

    return CPO_OK;
}
Exemple #7
0
int config_get_noption(calipso_config_t *config, const char *opt , const char *section)
{
	const char *val = config_get_option(config, opt , section );
	return val ? atoi(val) : 0;
}
Exemple #8
0
// NOTE: this function needs to call RegisterServiceCtrlHandlerEx and
// SetServiceStatus in all circumstances if brickd is running as service
static int generic_main(bool log_to_file, bool debug, bool libusb_debug) {
	int exit_code = EXIT_FAILURE;
	const char *mutex_name = "Global\\Tinkerforge-Brick-Daemon-Single-Instance";
	HANDLE mutex_handle = NULL;
	bool fatal_error = false;
	DWORD service_exit_code = NO_ERROR;
	int rc;
	char filename[1024];
	int i;
	FILE *log_file = NULL;
	WSADATA wsa_data;
	DEV_BROADCAST_DEVICEINTERFACE notification_filter;
	HDEVNOTIFY notification_handle;

	mutex_handle = OpenMutex(SYNCHRONIZE, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		rc = GetLastError();

		if (rc == ERROR_ACCESS_DENIED) {
			rc = service_is_running();

			if (rc < 0) {
				fatal_error = true;
				// FIXME: set service_exit_code

				goto error_mutex;
			} else if (rc) {
				fatal_error = true;
				service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

				log_error("Could not start as %s, another instance is already running as service",
				          _run_as_service ? "service" : "console application");

				goto error_mutex;
			}
		}

		if (rc != ERROR_FILE_NOT_FOUND) {
			fatal_error = true;
			// FIXME: set service_exit_code
			rc += ERRNO_WINAPI_OFFSET;

			log_error("Could not open single instance mutex: %s (%d)",
			          get_errno_name(rc), rc);

			goto error_mutex;
		}
	}

	if (mutex_handle != NULL) {
		fatal_error = true;
		service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

		log_error("Could not start as %s, another instance is already running",
		          _run_as_service ? "service" : "console application");

		goto error_mutex;
	}

	mutex_handle = CreateMutex(NULL, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		fatal_error = true;
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not create single instance mutex: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_mutex;
	}

	if (log_to_file) {
		if (GetModuleFileName(NULL, filename, sizeof(filename)) == 0) {
			rc = ERRNO_WINAPI_OFFSET + GetLastError();

			log_warn("Could not get module file name: %s (%d)",
			         get_errno_name(rc), rc);
		} else {
			i = strlen(filename);

			if (i < 4) {
				log_warn("Module file name '%s' is too short", filename);
			} else {
				filename[i - 3] = '\0';
				string_append(filename, "log", sizeof(filename));

				log_file = fopen(filename, "a+");

				if (log_file == NULL) {
					log_warn("Could not open log file '%s'", filename);
				} else {
					printf("Logging to '%s'\n", filename);

					log_set_file(log_file);
				}
			}
		}
	} else if (_run_as_service) {
		log_set_file(NULL);
	}

	if (!_run_as_service &&
	    !SetConsoleCtrlHandler(console_ctrl_handler, TRUE)) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_warn("Could not set console control handler: %s (%d)",
		         get_errno_name(rc), rc);
	}

	log_set_debug_override(debug);

	log_set_level(LOG_CATEGORY_EVENT, config_get_option("log_level.event")->value.log_level);
	log_set_level(LOG_CATEGORY_USB, config_get_option("log_level.usb")->value.log_level);
	log_set_level(LOG_CATEGORY_NETWORK, config_get_option("log_level.network")->value.log_level);
	log_set_level(LOG_CATEGORY_HOTPLUG, config_get_option("log_level.hotplug")->value.log_level);
	log_set_level(LOG_CATEGORY_HARDWARE, config_get_option("log_level.hardware")->value.log_level);
	log_set_level(LOG_CATEGORY_WEBSOCKET, config_get_option("log_level.websocket")->value.log_level);
	log_set_level(LOG_CATEGORY_OTHER, config_get_option("log_level.other")->value.log_level);

	if (config_has_error()) {
		log_error("Error(s) in config file '%s', run with --check-config option for details",
		          _config_filename);

		fatal_error = true;

		goto error_config;
	}

	if (_run_as_service) {
		log_info("Brick Daemon %s started (as service)", VERSION_STRING);
	} else {
		log_info("Brick Daemon %s started", VERSION_STRING);
	}

	if (config_has_warning()) {
		log_warn("Warning(s) in config file '%s', run with --check-config option for details",
		         _config_filename);
	}

	// initialize service status
error_config:
error_mutex:
	if (_run_as_service) {
		if (service_init(service_control_handler) < 0) {
			// FIXME: set service_exit_code
			goto error;
		}

		if (!fatal_error) {
			// service is starting
			service_set_status(SERVICE_START_PENDING, NO_ERROR);
		}
	}

	if (fatal_error) {
		goto error;
	}

	// initialize WinSock2
	if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + WSAGetLastError();

		log_error("Could not initialize Windows Sockets 2.2: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_event;
	}

	if (event_init() < 0) {
		// FIXME: set service_exit_code
		goto error_event;
	}

	if (hardware_init() < 0) {
		// FIXME: set service_exit_code
		goto error_hardware;
	}

	if (usb_init(libusb_debug) < 0) {
		// FIXME: set service_exit_code
		goto error_usb;
	}

	// create notification pipe
	if (pipe_create(&_notification_pipe) < 0) {
		// FIXME: set service_exit_code

		log_error("Could not create notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto error_pipe;
	}

	if (event_add_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, forward_notifications, NULL) < 0) {
		// FIXME: set service_exit_code
		goto error_pipe_add;
	}

	// register device notification
	ZeroMemory(&notification_filter, sizeof(notification_filter));

	notification_filter.dbcc_size = sizeof(notification_filter);
	notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	notification_filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;

	if (_run_as_service) {
		notification_handle = RegisterDeviceNotification((HANDLE)service_get_status_handle(),
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_SERVICE_HANDLE);
	} else {
		if (message_pump_start() < 0) {
			// FIXME: set service_exit_code
			goto error_pipe_add;
		}

		notification_handle = RegisterDeviceNotification(_message_pump_hwnd,
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_WINDOW_HANDLE);
	}

	if (notification_handle == NULL) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not register for device notification: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_notification;
	}

	if (network_init() < 0) {
		// FIXME: set service_exit_code
		goto error_network;
	}

	// running
	if (_run_as_service) {
		service_set_status(SERVICE_RUNNING, NO_ERROR);
	}

	if (event_run(network_cleanup_clients_and_zombies) < 0) {
		// FIXME: set service_exit_code
		goto error_run;
	}

	exit_code = EXIT_SUCCESS;

error_run:
	network_exit();

error_network:
	UnregisterDeviceNotification(notification_handle);

error_notification:
	if (!_run_as_service) {
		message_pump_stop();
	}

	event_remove_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

error_pipe_add:
	pipe_destroy(&_notification_pipe);

error_pipe:
	usb_exit();

error_usb:
	hardware_exit();

error_hardware:
	event_exit();

error_event:
	log_info("Brick Daemon %s stopped", VERSION_STRING);

error:
	if (!_run_as_service) {
		// unregister the console handler before exiting the log. otherwise a
		// control event might be send to the control handler after the log
		// is not available anymore and the control handler tries to write a
		// log messages triggering a crash. this situation could easily be
		// created by clicking the close button of the command prompt window
		// while the getch call is waiting for the user to press a key.
		SetConsoleCtrlHandler(console_ctrl_handler, FALSE);
	}

	log_exit();

	config_exit();

	if (_run_as_service) {
		// because the service process can be terminated at any time after
		// entering SERVICE_STOPPED state the mutex is closed beforehand,
		// even though this creates a tiny time window in which the service
		// is still running but the mutex is not held anymore
		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}

		// service is now stopped
		service_set_status(SERVICE_STOPPED, service_exit_code);
	} else {
		if (_pause_before_exit) {
			printf("Press any key to exit...\n");
			getch();
		}

		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}
	}

	return exit_code;
}
Exemple #9
0
int main(int argc, char **argv) {
	int exit_code = EXIT_FAILURE;
	int i;
	bool help = false;
	bool version = false;
	bool check_config = false;
	bool daemon = false;
	bool debug = false;
	bool libusb_debug = false;
	int pid_fd = -1;
#ifdef BRICKD_WITH_LIBUDEV
	bool initialized_udev = false;
#endif

	for (i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "--help") == 0) {
			help = true;
		} else if (strcmp(argv[i], "--version") == 0) {
			version = true;
		} else if (strcmp(argv[i], "--check-config") == 0) {
			check_config = true;
		} else if (strcmp(argv[i], "--daemon") == 0) {
			daemon = true;
		} else if (strcmp(argv[i], "--debug") == 0) {
			debug = true;
		} else if (strcmp(argv[i], "--libusb-debug") == 0) {
			libusb_debug = true;
		} else {
			fprintf(stderr, "Unknown option '%s'\n\n", argv[i]);
			print_usage();

			return EXIT_FAILURE;
		}
	}

	if (help) {
		print_usage();

		return EXIT_SUCCESS;
	}

	if (version) {
		printf("%s\n", VERSION_STRING);

		return EXIT_SUCCESS;
	}

	if (prepare_paths() < 0) {
		return EXIT_FAILURE;
	}

	if (check_config) {
		return config_check(_config_filename) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
	}

	config_init(_config_filename);

	log_init();

	if (daemon) {
		pid_fd = daemon_start(_log_filename, _pid_filename, true);
	} else {
		pid_fd = pid_file_acquire(_pid_filename, getpid());

		if (pid_fd == PID_FILE_ALREADY_ACQUIRED) {
			fprintf(stderr, "Already running according to '%s'\n", _pid_filename);
		}
	}

	if (pid_fd < 0) {
		goto error_log;
	}

	log_set_debug_override(debug);

	log_set_level(LOG_CATEGORY_EVENT, config_get_option("log_level.event")->value.log_level);
	log_set_level(LOG_CATEGORY_USB, config_get_option("log_level.usb")->value.log_level);
	log_set_level(LOG_CATEGORY_NETWORK, config_get_option("log_level.network")->value.log_level);
	log_set_level(LOG_CATEGORY_HOTPLUG, config_get_option("log_level.hotplug")->value.log_level);
	log_set_level(LOG_CATEGORY_HARDWARE, config_get_option("log_level.hardware")->value.log_level);
	log_set_level(LOG_CATEGORY_WEBSOCKET, config_get_option("log_level.websocket")->value.log_level);
#ifdef BRICKD_WITH_RED_BRICK
	log_set_level(LOG_CATEGORY_RED_BRICK, config_get_option("log_level.red_brick")->value.log_level);
	log_set_level(LOG_CATEGORY_SPI, config_get_option("log_level.spi")->value.log_level);
	log_set_level(LOG_CATEGORY_RS485, config_get_option("log_level.rs485")->value.log_level);
#endif
	log_set_level(LOG_CATEGORY_OTHER, config_get_option("log_level.other")->value.log_level);

	if (config_has_error()) {
		log_error("Error(s) in config file '%s', run with --check-config option for details",
		          _config_filename);

		goto error_config;
	}

	if (daemon) {
		log_info("Brick Daemon %s started (daemonized)", VERSION_STRING);
	} else {
		log_info("Brick Daemon %s started", VERSION_STRING);
	}

	if (config_has_warning()) {
		log_error("Warning(s) in config file '%s', run with --check-config option for details",
		          _config_filename);
	}

	if (event_init() < 0) {
		goto error_event;
	}

	if (signal_init(handle_sigusr1) < 0) {
		goto error_signal;
	}

	if (hardware_init() < 0) {
		goto error_hardware;
	}

	if (usb_init(libusb_debug) < 0) {
		goto error_usb;
	}

#ifdef BRICKD_WITH_LIBUDEV
	if (!usb_has_hotplug()) {
		if (udev_init() < 0) {
			goto error_udev;
		}

		initialized_udev = true;
	}
#endif

	if (network_init() < 0) {
		goto error_network;
	}

#ifdef BRICKD_WITH_RED_BRICK
	if (gpio_init() < 0) {
		goto error_gpio;
	}

	if (red_usb_gadget_init() < 0) {
		goto error_red_usb_gadget;
	}

	if (redapid_init() < 0) {
		goto error_redapid;
	}

	if (red_stack_init() < 0) {
		goto error_red_stack;
	}

	if (rs485_extension_init() < 0) {
		goto error_rs485_extension;
	}
#endif

	if (event_run(network_cleanup_clients_and_zombies) < 0) {
		goto error_run;
	}

	exit_code = EXIT_SUCCESS;

error_run:
#ifdef BRICKD_WITH_RED_BRICK
	rs485_extension_exit();

error_rs485_extension:
	red_stack_exit();
    
error_red_stack:
	redapid_exit();

error_redapid:
	red_usb_gadget_exit();

error_red_usb_gadget:
	//gpio_exit();

error_gpio:
#endif
	network_exit();

error_network:
#ifdef BRICKD_WITH_LIBUDEV
	if (initialized_udev) {
		udev_exit();
	}

error_udev:
#endif
	usb_exit();

error_usb:
	hardware_exit();

error_hardware:
	signal_exit();

error_signal:
	event_exit();

error_event:
	log_info("Brick Daemon %s stopped", VERSION_STRING);

error_config:
error_log:
	log_exit();

	if (pid_fd >= 0) {
		pid_file_release(_pid_filename, pid_fd);
	}

	config_exit();

	return exit_code;
}
Exemple #10
0
/** 
 * Print given option to stdout 
 * @param cfg: config
 * @param opt: option name without trailing :. 
 *	This is different from config_set_option.
 */
static void
print_option(struct config_file* cfg, const char* opt)
{
	if(!config_get_option(cfg, opt, config_print_func, stdout))
		fatal_exit("cannot print option '%s'", opt);
}
Exemple #11
0
static
int login_setforward_user(struct clientinfo* clntinfo) {

	const char* forward;
	struct slist_t* forward_list, *forward_list_cur;
	char* tmp;
	int newsize;
	int config_state = TAG_GLOBAL | TAG_FROM | TAG_PORT
			 | TAG_TIME | TAG_SERVERTYPE
			 | TAG_PROXYIP | TAG_PROXYPORT;

	/* this is already a forward */
	if ( clntinfo->before_forward.user ) {
		return CMD_HANDLED;
	}

	if ( clntinfo->destination ) {
		config_state |= TAG_TO;
	}

	if ( clntinfo->user ) {
		config_state |= TAG_USER;
	}

	config_shrink_config(get_uint_ip(GET_IP_CLIENT, clntinfo),
			get_uint_ip(GET_IP_SERVER, clntinfo),
			clntinfo->destination,
			clntinfo->destinationport,
			clntinfo->user,
			-1,          /* before_forward.dest_ip */
			(char*) 0,   /* before_forward.destination */
			0,           /* before_forward.destinationport */
			(char*) 0,   /* before_forward.user */
			0,		/* set no specific time */
			clntinfo->proxy_ip,
			clntinfo->proxy_port,
			srvinfo.servertype,
			&hostcache,
			config_state);

	if (config_compare_option("access", "allow") == 0) {
		say(clntinfo->clientsocket, "531 You are not allowed to "
			"connect to that host. Goodbye.\r\n");
		jlog(5, "%s was not allowed to connect.",
					conv_ip_to_char(clntinfo->client_ip));
		return CMD_ERROR;
	}

	/* see if there is an option for the forward */
	forward = config_get_option("forward");

	if (! forward) {
		/* no forward */
		lcs.userlogin = strnulldup(clntinfo->user);
		lcs.usereffective = strnulldup(clntinfo->user);
		if (lcs.userforwarded) { free(lcs.userforwarded); }
		lcs.userforwarded = strdup("<no forward>");
		enough_mem(lcs.userforwarded);
		return CMD_HANDLED;
	}

	/*
	 * <user ftp>
	 *    forward [email protected]
	 *    forward [email protected],3949,p
	 *    forward [email protected]     *     johnspass
	 *    forward [email protected]   JiKe94  johnspass
	 * </user>
	 *    forward *@fooserver.com:2378
	 *    forward %@fooserver.com:2378
	 */

	/* split the list into tokens */
	if ( ! (forward_list = config_split_line( forward, WHITESPACES )) ) {
		return CMD_HANDLED;
	}

	/* if we have a defaultforward setting, the variable user has to be
	 * defined so that we can decide if we can use defaultforward at
	 * all. If this is not the case, but there is a defaultforward
	 * setting, skip this whole part. This can happen by setting
	 * logintime to "connect" */
	if (!clntinfo->user &&
	    forward_list->value &&
	    forward_list->value[0] == '%' &&
	    forward_list->value[1] == '@') {
		slist_destroy(forward_list);
		return CMD_HANDLED;
	}

	/* if there is a defaultforward but we already have a destination
	 * set, we can quit here as well */
	if (clntinfo->destination &&
	    forward_list->value &&
	    forward_list->value[0] == '%' &&
	    forward_list->value[1] == '@') {
		/* no forward is being used */
		lcs.userlogin = strnulldup(clntinfo->user);
		lcs.usereffective = strnulldup(clntinfo->user);
		if (lcs.userforwarded) { free(lcs.userforwarded); }
		lcs.userforwarded = strdup("<no forward>");
		enough_mem(lcs.userforwarded);
		slist_destroy(forward_list);
		return CMD_HANDLED;
	}


	forward_list_cur = forward_list;

	/* read and save the values */
	clntinfo->forward.login = strdup(forward_list_cur->value);
	enough_mem(clntinfo->forward.login);

	forward_list_cur = forward_list_cur->next;

	if (forward_list_cur && forward_list_cur->value) {
		clntinfo->forward.accept_pw = strdup(forward_list_cur->value);
		enough_mem(clntinfo->forward.accept_pw);
	} else {
		clntinfo->forward.accept_pw = (char*) 0;
	}

	if (forward_list_cur) {
		forward_list_cur = forward_list_cur->next;
	}
	if (forward_list_cur && forward_list_cur->value) {
		clntinfo->forward.send_pw = strdup(forward_list_cur->value);
		enough_mem(clntinfo->forward.send_pw);
	} else {
		clntinfo->forward.send_pw = (char*) 0;
	}
	/* destroy the list again, we have saved the values into
	 * clntinfo->forward.<field>    */
	slist_destroy(forward_list);

	/* delete those configuration values that are evaluated by the
	 * parsing routine  -  they are not necessary anymore */
	config_option_list_delete("transparent-forward");
	config_option_list_delete("forward");

	/* back up */
	clntinfo->before_forward.user = strnulldup(clntinfo->user);
	clntinfo->before_forward.destination
			= strnulldup(clntinfo->destination);
	clntinfo->before_forward.destinationport = clntinfo->destinationport;
	clntinfo->before_forward.dest_ip = get_uint_ip(GET_IP_SERVER,clntinfo);

	/* special case: We don't have set a username. The client could have
	 * used logintime == connect and has a forward that already matches */
	if ( ! clntinfo->before_forward.user ) {
		clntinfo->before_forward.user = malloc(2);
		enough_mem(clntinfo->before_forward.user);
		clntinfo->before_forward.user[0] = '*';
		clntinfo->before_forward.user[1] = '\0';
	}

	/* if there was only a new destination but no new username given,
	 * prepend the old one */
	if ( ! strchr(clntinfo->forward.login, '@')
			&& clntinfo->before_forward.user) {
		newsize = strlen(clntinfo->before_forward.user)
			  + 1 /* @ */
			  + strlen(clntinfo->forward.login)
			  + 1 /* term */;

		tmp = (char*) malloc(newsize);
		enough_mem(tmp);
		snprintf( tmp, newsize, "%s@%s", clntinfo->before_forward.user,
						 clntinfo->forward.login);
		free(clntinfo->forward.login);
		clntinfo->forward.login = tmp;
	}

	if (clntinfo->forward.login[0] == '*' &&
	    clntinfo->forward.login[1] == '@') {
		/* passauth */
		clntinfo->forward.passauth = 1;
	}

	/* If there is still no destination, see if we have a defaultforward
	 * setting */
	if (clntinfo->destination == (char*) 0 &&
	    clntinfo->user &&
	    clntinfo->forward.login[0] == '%' &&
	    clntinfo->forward.login[1] == '@') {
		/* defaultforward */
		int newsize = strlen(&(clntinfo->forward.login[1])) +
				strlen(clntinfo->user) + 1;
		char* tmp = (char*) malloc(newsize);
		enough_mem(tmp);
		snprintf(tmp, newsize, "%s%s", clntinfo->user,
					&(clntinfo->forward.login[1]));
		free(clntinfo->forward.login);
		clntinfo->forward.login = tmp;
		jlog(8, "No destination was set. Using %s because of defaultforward setting", clntinfo->forward.login);
	}

	/* call the parsing routine and let it set the values */
	if (set_userdest(clntinfo->forward.login, 0, clntinfo, "@,: \t") < 0) {
		return CMD_ERROR;
	}

	/* set values for log info struct */
	lcs.userlogin = strnulldup(clntinfo->before_forward.user);
	lcs.usereffective = strnulldup(clntinfo->user);
	lcs.userforwarded = strnulldup(clntinfo->forward.login);

	/* shrink the configuration again - with TAG_FORWARDED this time */

	config_shrink_config(get_uint_ip(GET_IP_CLIENT, clntinfo),
			/* these are the original values */
			/* see above (1) */
			clntinfo->before_forward.dest_ip,
			clntinfo->before_forward.destination,
			clntinfo->before_forward.destinationport,
			clntinfo->before_forward.user,
			/* these are the values set by the forward */
			/* pass them as well, if we are in the
			 * forwarded_tag, config_match_section()
			 * will overwrite the previous with the
			 * following values */
			get_uint_ip(GET_IP_SERVER, clntinfo),
			clntinfo->destination,
			clntinfo->destinationport,
			clntinfo->user,

			0,		/* set no specific time */

			clntinfo->proxy_ip,
			clntinfo->proxy_port,

			srvinfo.servertype, &hostcache,
			TAG_ALL);

	return CMD_HANDLED;
}
Exemple #12
0
static
int login_mayconnect(struct clientinfo* clntinfo) {
	int allowed = 0;
	unsigned long int target;
	unsigned long int host_ip;
	unsigned long int client_ip, server_ip;
	int tags;

	allowed = 0;

	/* we don't know yet if clntinfo->destination is a hostname like
	 * "somehost.foo.com" or if it is an IP in a char* like
	 * "212.117.232.20"
	 *
	 * So call inet_addr(), it should make the decision  :-)
	 *
	 * */
	target = inet_addr(clntinfo->destination);

	/* get the client_ip by asking information about the socket the
	 * client is connected */
	client_ip = get_uint_ip(GET_IP_CLIENT, clntinfo);
	server_ip = (unsigned long int) UINT_MAX;

	if (target == (unsigned long int) UINT_MAX) {
		/* clntinfo->destination may be a hostname, but it needn't.
		 * It may also be an invalid IP: "393.39.239.500" or
		 * anything else. Look it up.
		 * */
		host_ip = hostent_get_ip(&hostcache, clntinfo->destination);
		if (host_ip != (unsigned long int) UINT_MAX) {
			/* successful lookup */
			server_ip = host_ip;
		} else {
			/* it's not a valid IP and we could not look it up,
			 * so we could not get valid information about the
			 * destination host */
			jlog(7, "Nonsense destination (no IP and could not look up hostname): %s",
					clntinfo->destination);
			jlog(8, "Please check your nameserver configuration. This may also happen if your chroot-environment does not contain the necessary files which the libc needs for a lookup");
			allowed = 0;
		}
	} else {
		/* okay, it's an IP */
		server_ip = inet_addr(clntinfo->destination);
	}

	if (server_ip != (unsigned long) UINT_MAX) {
		/* we could get a valid IP, now we can evaluate if client
		 * is allowed to connect to the destination host */
		jlog(9, "Checking all tags");
		tags = TAG_ALL_NOT_FORWARDED;
		if (clntinfo->before_forward.user) {
			/* if we are treating a forward, add this value, it
			 * won't come up in the option list otherwise */
			tags |= TAG_FORWARDED;
		}
		/* checking of the configuration works such:
		 *
		 * no forward:   do not evaluate <forwarded>
		 *               always check the normal values
		 *
		 * forward:      evaluate <forwarded>
		 *               if (!in_forwarded_tag) {
		 *     (1)             check before_forward.* values
		 *               } else {
		 *     (2)             check normal values
		 *               }
		 */
		if (clntinfo->before_forward.user) {
			/* Yes, there was a forward applied */
			config_shrink_config(client_ip,
				/* this are the original values */
				/* see above (1) */
				clntinfo->before_forward.dest_ip,
				clntinfo->before_forward.destination,
				clntinfo->before_forward.destinationport,
				clntinfo->before_forward.user,
				/* these are the values set by the forward */
				/* pass them as well, if we are in the
				 * forwarded_tag, config_match_section()
				 * will overwrite the previous with the
				 * following values */
				server_ip,
				clntinfo->destination,
				clntinfo->destinationport,
				clntinfo->user,
				0,		/* set no specific time */
				clntinfo->proxy_ip,
				clntinfo->proxy_port,
				srvinfo.servertype,
				&hostcache,
				tags);
		} else {
			/* not a forward */
			config_shrink_config(client_ip,
				server_ip,
				clntinfo->destination,
				clntinfo->destinationport,
				clntinfo->user,
				clntinfo->before_forward.dest_ip,
				clntinfo->before_forward.destination,
				clntinfo->before_forward.destinationport,
				clntinfo->before_forward.user,
				0,		/* set no specific time */
				clntinfo->proxy_ip,
				clntinfo->proxy_port,
				srvinfo.servertype,
				&hostcache,
				tags);
		}

		allowed = strcmp(config_get_option("access"), "allow") == 0;
	}

	if (!allowed) {
		say(clntinfo->clientsocket, "531 You are not allowed to connect to that host.\r\n");
		jlog(8, "Not allowed to connect to %s", clntinfo->destination);
		lcs.respcode = 531;
		return CMD_ERROR;
	}
	/* if the client was allowed, save the clients original IP */
	if (!clntinfo->before_forward.user) {
		clntinfo->before_forward.dest_ip = server_ip;
	}
	return allowed;  /* a positive int */
}
Exemple #13
0
int main(int argc, char **argv) {
	cl_options_t cl_options = {0};

	dbg_init();
	DBG_LOG("Version %s", g_version);

	ui = &ui_sdlgl;

	printf("DreamChess %s\n", g_version);

	parse_options(argc, argv, &ui, &cl_options);
	config_init();
	set_cl_options(&cl_options);

	if (!ui) {
		DBG_ERROR("Failed to find a user interface driver");
		exit(1);
	}

	ui->init();

	init_resolution();

	while (1) {
		board_t board;
		int pgn_slot;
		option_t *option;

		if (!(config = ui->config(&pgn_slot)))
			break;

		ch_userdir();
		option = config_get_option("first_engine");

#ifdef __APPLE__
		char temp1[200];
		char temp2[200];

		if (!strcmp(option->string, "dreamer") || !strcmp(option->string, "Dreamer")) {
			CFBundleRef mainBundle = CFBundleGetMainBundle();

			CFURLRef bundledir = CFBundleCopyBundleURL(mainBundle);
			CFStringRef stringref = CFURLCopyFileSystemPath(bundledir, kCFURLPOSIXPathStyle);
			CFStringGetCString(stringref, temp1, 200, kCFStringEncodingMacRoman);

			snprintf(temp2, sizeof(temp2), "%s/contents/MacOS/dreamer", temp1);

			game_set_engine_error(comm_init(temp2));
		} else
			game_set_engine_error(comm_init(option->string));
#else
		game_set_engine_error(comm_init(option->string));
#endif

		comm_send("xboard\n");

		comm_send("new\n");
		comm_send("random\n");

		comm_send("sd %i\n", config->cpu_level);
		comm_send("depth %i\n", config->cpu_level);

		if (config->difficulty == 0)
			comm_send("noquiesce\n");

		if (config->player[WHITE] == PLAYER_UI && config->player[BLACK] == PLAYER_UI)
			comm_send("force\n");

		if (config->player[WHITE] == PLAYER_ENGINE)
			comm_send("go\n");

		in_game = 1;
		board_setup(&board);
		history = history_init(&board);
		move_list_init(&san_list);
		move_list_init(&fan_list);
		move_list_init(&fullalg_list);

		if (pgn_slot >= 0)
			if (game_load(pgn_slot)) {
				DBG_ERROR("Failed to load savegame in slot %i", pgn_slot);
				exit(1);
			}

		ui->update(history->view->board, NULL);
		while (in_game) {
			char *s;

			if ((s = comm_poll())) {
				DBG_LOG("Message from engine: '%s'", s);
				if (!history->result) {
					if ((!strncmp(s, "move ", 4) || strstr(s, "... ")) &&
						config->player[history->last->board->turn] == PLAYER_ENGINE) {
						char *move_str = strrchr(s, ' ') + 1;
						board_t new_board = *history->last->board;
						move_t *engine_move;

						DBG_LOG("Parsing move string '%s'", move_str);

						engine_move = san_to_move(&new_board, move_str);
						if (!engine_move)
							engine_move = fullalg_to_move(&new_board, move_str);
						if (engine_move) {
							audio_play_sound(AUDIO_MOVE);
							do_move(engine_move, 1);
							free(engine_move);
						} else
							DBG_ERROR("Failed to parse move string '%s'", move_str);
					} else if (strstr(s, "llegal move"))
						game_undo();
					/* Ignore result message if we've already determined a result ourselves. */
					else {
						char *start = strchr(s, '{');
						char *end = strchr(s, '}');

						if (start && end && end > start) {
							char *comment = malloc(end - start);
							history->result = malloc(sizeof(result_t));
							strncpy(comment, start + 1, end - start - 1);
							comment[end - start - 1] = '\0';
							history->result->reason = comment;
							if (strstr(s, "1-0")) {
								history->result->code = RESULT_WHITE_WINS;
								ui->show_result(history->result);
							} else if (strstr(s, "1/2-1/2")) {
								history->result->code = RESULT_DRAW;
								ui->show_result(history->result);
							} else if (strstr(s, "0-1")) {
								history->result->code = RESULT_BLACK_WINS;
								ui->show_result(history->result);
							} else {
								free(history->result->reason);
								free(history->result);
								history->result = NULL;
							}
						}
					}
				}

				free(s);
			}
			ui->poll();
		}
		comm_send("quit\n");
		comm_exit();
		history_exit(history);
		move_list_exit(&san_list);
		move_list_exit(&fan_list);
		move_list_exit(&fullalg_list);
	}
	ui->exit();
	dbg_exit();
	return 0;
}
Exemple #14
0
void toggle_fullscreen(void) {
	option_t *option = config_get_option("full_screen");
	option_select_value_by_index(option, 1 - option->selected->index);
	set_resolution(0);
}
Exemple #15
0
static int dialog_title_theme(gg_widget_t *widget, gg_widget_t *emitter, void *data, void *extra_data) {
	option_t *option = config_get_option("theme");
	option_select_value_by_index(option, gg_option_get_selected(GG_OPTION(widget)));
	return 1;
}
Exemple #16
0
static
int child_setup(int sock_fd, struct clientinfo *clntinfo) {
	struct sockaddr_in t_in;
	struct sockaddr_in c_in;
	unsigned long int peer_ip = get_uint_peer_ip(sock_fd);
	struct sigaction sa;
	int i, ret;
#ifdef HAVE_LIBWRAP
	struct request_info req;
	int libwrap_allow = 0;
#endif

	if (peer_ip == (unsigned long int) UINT_MAX) {
		return -1;
	}

	if (stage_action("connect") < 0) {
		say(sock_fd, "421 Error setting up (see logfile)\r\n");
		return -1;
	}

	/* The clients ignore the SIGHUP signal. Thus
	 * the user can issue a killall -HUP jftpgw
	 * and the master jftpgw process rereads its
	 * configuration file without affecting the
	 * child servers */

	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGHUP, &sa, 0);

	/* And they just reap the status of exited children
	 */
	sa.sa_handler = reap_chld_info;
	sigemptyset(&sa.sa_mask);
#ifndef WINDOWS
	sa.sa_flags = SA_RESTART;
#endif
	sigaction(SIGCHLD, &sa, 0);

	for (i = 0; i < clntinfo->boundsocket_niface; i++) {
		close(clntinfo->boundsocket_list[i]);
	}
	free(clntinfo->boundsocket_list);
	clntinfo->boundsocket_list = (int*) 0;

	clntinfo->forward.passauth = 0;
	clntinfo->serversocket = -1;

	clntinfo->clientsocket = sock_fd;
	jlog(7, "Connection from %s", get_char_peer_ip(sock_fd));
	c_in = socketinfo_get_local_sin(sock_fd);
	jlog(7, "Client tried to connect to %s on port %d",
					inet_ntoa(c_in.sin_addr),
					ntohs(c_in.sin_port));

	clntinfo->addr_to_client = c_in.sin_addr.s_addr;
	clntinfo->proxy_ip = c_in.sin_addr.s_addr;
	clntinfo->proxy_port = ntohs(c_in.sin_port);

	/* see if we are in transparent mode */
	t_in = socketinfo_get_transparent_target_sin(sock_fd);
	jlog(7, "Transparent target seems to be %s on port %d",
					inet_ntoa(t_in.sin_addr),
					ntohs(t_in.sin_port));

	jlog(9, "Checking TAG_GLOBAL | TAG_FROM | TAG_PROXYIP | TAG_PROXYPORT | TAG_TIME | TAG_SERVERTYPE");
	ret = config_shrink_config(peer_ip,	/* source IP */
				-1,		/* dest IP */
				(char*) 0,	/* dest name */
				0,		/* dest port */
				(char*) 0,	/* dest user */
				-1,		/* forwarded IP */
				(char*) 0,	/* forwarded destination */
				0,		/* forwarded destinationport */
				(char*) 0,	/* forwarded username */
				0,		/* set no specific time */
				clntinfo->proxy_ip,   /* ip of proxy if   */
				clntinfo->proxy_port, /* port of proxy if */
				srvinfo.servertype,   /* global variable */
				&hostcache,
				TAG_CONNECTED
				);
	if (ret != 0) {
		jlog(2, "Error shrinking config data");
		return ret;
	}

#ifndef HAVE_LIBWRAP
	srvinfo.tcp_wrapper = 0;
#endif

	if (srvinfo.tcp_wrapper) {
#ifdef HAVE_LIBWRAP
		/* use libwrap(tcp_wrapper) for access control
		 *   patch by <*****@*****.**>.
		 * It is useful to check both keywords "jftpgw" and "ftp-gw"
		 * for TIS Gauntlet flabour.  
		 */
		request_init(&req, 
			     RQ_DAEMON, "ftp-gw", 
			     RQ_CLIENT_ADDR, conv_ip_to_char(peer_ip),
			     NULL);
		libwrap_allow = hosts_access(&req);

		request_init(&req, 
			     RQ_DAEMON, "jftpgw", 
			     RQ_CLIENT_ADDR, conv_ip_to_char(peer_ip),
			     NULL);

		if (libwrap_allow || hosts_access(&req)) {
			jlog(5, "%s is allowed by libwrap to connect.", 
					conv_ip_to_char(peer_ip));
		}
		else {
			say(sock_fd, "500 You are not allowed by libwrap to "
					"connect. Goodbye.\r\n");
			jlog(5, "%s was not allowed to connect.",
					conv_ip_to_char(peer_ip));
			close(sock_fd);
			return -2;
		}
#endif
	} else {
		if ( ! config_get_option("access")
			||
			! strcmp(config_get_option("access"), "allow") == 0) {

			say(sock_fd, "500 You are not allowed to "
				"connect. Goodbye.\r\n");
			jlog(5, "%s was not allowed to connect.",
						conv_ip_to_char(peer_ip));
			close(sock_fd);
			return -2;
		} else {
			jlog(6, "%s is allowed to connect.",
					conv_ip_to_char(peer_ip));
		}
	}

	if (config_get_bool("transparent-proxy") && 
			get_uint_peer_ip(sock_fd) == t_in.sin_addr.s_addr) {
		jlog(4, "proxy loop detected - machine connects to itself, disabling transparent proxy support");
	}

	jlog(9, "Proxy loop check: peer_ip: %s, t_in_ip: %s",
		get_char_peer_ip(sock_fd), inet_ntoa(t_in.sin_addr));
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
	jlog(9, "HAVE_LINUX_NETFILTER_IPV4_H true, c_in_ip: %s, t_in_port: %d, "
		"c_in_port: %d", inet_ntoa(c_in.sin_addr),
		ntohs(t_in.sin_port), ntohs(c_in.sin_port));
#endif
	if (config_get_bool("transparent-proxy")
			&&
		/* see if the proxy loops. It loops when the source has the
		 * same IP as the destination. There is no need for such a
		 * configuration "in the wild". Is there? */
		(!(get_uint_peer_ip(sock_fd) == t_in.sin_addr.s_addr)
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
			&& !(t_in.sin_addr.s_addr == c_in.sin_addr.s_addr
				&&
			    t_in.sin_port == c_in.sin_port)
#endif
		)) {

		jlog(9, "Enabling transparent proxy");
		clntinfo->transparent = TRANSPARENT_YES;
		clntinfo->transparent_destination = t_in;
	} else {
		jlog(9, "No transparent proxy support");
		clntinfo->transparent = TRANSPARENT_NO;
		clntinfo->transparent_destination.sin_port = 0;
		clntinfo->transparent_destination.sin_addr.s_addr = 0;
	}

	if (stage_action("connectsetup") < 0) {
		say(sock_fd, "421 Error setting up (see logfile)\r\n");
		return -1;
	}

	/* set the target for the transparent proxy */
	if (clntinfo->transparent == TRANSPARENT_YES) {
		char* colon;
		long int dport;

		if (config_get_option("transparent-forward")
			&& config_compare_option("logintime", "connect")) {

			clntinfo->destination =
			      strdup(config_get_option("transparent-forward"));
			jlog(9, "Enabling transparent forward to %s",
					clntinfo->destination);
		} else {
			clntinfo->destination =
			      socketinfo_get_transparent_target_char(sock_fd);
		}
		colon = strchr(clntinfo->destination, ':');
		if (!colon) {
			/* abort, shouldnt happen */
			jlog(9, "Could not get transparent target properly");
			clntinfo->transparent = TRANSPARENT_NO;
			return say_welcome(sock_fd);
		}
		*colon = '\0';  /* terminate destination */
		colon++;        /* skip to port number   */
		dport = strtol(colon, NULL, 10);
		if (errno == ERANGE 
				&& (dport == LONG_MIN || dport == LONG_MAX)) {
			clntinfo->destinationport =
				config_get_ioption("serverport", DEFAULTSERVERPORT);
			/* reverse for logging */
			colon--; *colon = ':';
			jlog(6, "Could not parse dest/port to connect to: %s",
					clntinfo->destination);
			return -1;
		} else {
			clntinfo->destinationport = dport;
		}
	}
	if ( ! config_compare_option("logintime", "connect") ) {
		ret = say_welcome(sock_fd);
	} else {
		ret = login(clntinfo, LOGIN_ST_CONNECTED);
	}

	/* seed the random number generator */
	srand(time(NULL));

	return ret;
}
Exemple #17
0
int waitclient(const char* hostnames, struct clientinfo* clntinfo) {

	int chldpid =0;
	const char* option = 0;
	int ahandle, i;
	struct sigaction sa;
	struct descriptor_set d_set;
	unsigned int peer_ip;
	struct sockaddr_in c_in;
	time_t now;

	if (srvinfo.multithread) {
		daemonize();
	}

	if (changeid(UNPRIV, EUID,
				"Changing id back (socket(), bind())") < 0) {
		return -1;
	}

	d_set = listen_on_ifaces(hostnames, clntinfo);
	if (d_set.maxfd < 0) {
		jlog(8, "d_set.maxfd was negative: %d", d_set.maxfd);
		return -1;
	}

	/* we have successfully bound */

	/* become root again - use our function instead of plain
	 * setuid() for the logging */
	if (changeid(PRIV, UID, "Changing ID to root (pidfile)") < 0) {
		return -1;
	}

	option = config_get_option("pidfile");
	if (option) {
		FILE* pidf;
		umask(022);
		pidf = fopen(option, "w");
		if (pidf) {
			fprintf(pidf, "%ld\n", (long) getpid());
			fclose(pidf);
			/* if successful register function to remove the
			 * pidfile */
			atexit(removepidfile);
		} else {
			jlog(2, "Error creating pidfile %s", option);
		}
	}

	/* this has to be done for the daemonization. We do it now after
	 * the pidfile has been created */
	umask(0);

	srvinfo.ready_to_serve = SVR_LAUNCH_READY;

	if (stage_action("startsetup") < 0) {
		return -1;
	}

	sa.sa_handler = childterm;
	chlds_exited = 0;
	sigemptyset (&sa.sa_mask);
#ifndef WINDOWS
	sa.sa_flags = SA_RESTART;
#endif
	sigaction (SIGCHLD, &sa, 0);


	/* Close stdin,stdout,stderr */
	for(i = 0; i <= 2 && srvinfo.multithread; i++) {
		close(i);
	}
	srvinfo.main_server_pid = getpid();
	atexit(sayterminating);

	while(1) {
		ahandle = get_connecting_socket(d_set);
		if (ahandle == -1) {
			/* either select() or accept() failed */
			/* I don't try resume here because we are in an
			 * endless loop. The danger of the programm falling
			 * into an infinite loop consuming all cpu time is
			 * too big... */
			jlog(8, "get_connecting_socket() returned error code");
			return -1;
		}

		c_in = socketinfo_get_local_sin(ahandle);
		peer_ip = get_uint_peer_ip(ahandle);
		now = time(NULL);
		config_counter_increase(peer_ip,               /* from ip */
					c_in.sin_addr.s_addr,  /* proxy_ip */
					ntohs(c_in.sin_port),  /* proxy_port */
					now);               /* specific_time */
		if (config_check_limit_violation()) {
			say(ahandle, "500 Too many connections, sorry\r\n");
			close(ahandle);
			config_counter_decrease(peer_ip,       /* from ip */
					c_in.sin_addr.s_addr,  /* proxy_ip */
					ntohs(c_in.sin_port),  /* proxy_port */
					now);               /* specific_time */
			continue;
		}
		if (srvinfo.multithread) {
			if ((chldpid = fork()) < 0) {
				jlog(1, "Error forking: %s", strerror(errno));
				close(ahandle);
				return -1;
			}
			if (chldpid > 0) {
				/* parent process */
				/* register the PID */
				register_pid(chldpid, peer_ip,
					c_in.sin_addr.s_addr,  /* proxy_ip */
					ntohs(c_in.sin_port),  /* proxy_port */
					now);               /* specific_time */
				close(ahandle);
			}
			if (chldpid == 0) {
				/* child process */
				jlog(8, "forked to pid %d", getpid());
			}
		}
		if (!srvinfo.multithread || chldpid == 0) {
			return child_setup(ahandle, clntinfo);
		}
	}
}
Exemple #18
0
double config_get_foption(calipso_config_t *config, const char *opt , const char *section)
{
	const char *val = config_get_option(config, opt , section);
	return val ? atof(val) : 0.0;
}
Exemple #19
0
int main(int argc, char** argv)
{
	const char* pcap_file;
	const char* capture_interface;
	const char* tmp;
	int is_live = 0;
	int snaplen = 65535;
	uint32_t packet_pool_size = 1;
	pthread_t worker_id;
	uint32_t conn_no = 0;
	uint32_t conn_max = 0;
	uint32_t flow_timeout = 0;
	int print_stats_enabled = 0;

	if (argc != 2) {
		usage(argv[0]);
		return -1;
	}

	msg_setlevel(MSG_INFO);

	// install signal handler
	if (SIG_ERR == signal(SIGINT, sig_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGINT.");
		return -1;
	}
	if (SIG_ERR == signal(SIGCHLD, sig_chld_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGCHLD");
		return -1;
	}

	struct dumpers dumps;
	dumpers_init(&dumps);

	struct config* conf = config_new(argv[1]);
	if (!conf) {
		msg(MSG_ERROR, "Invalid config. Abort!");
		return 0;
	}

	// check if we should have any output over msg
	// quite mode is necessary when we are dumping to stdout
	tmp = config_get_option(conf, MAIN_NAME, "quiet");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			msg_setlevel(-1);
		}
	}
	
	// check if we have a config statement that changes message level
	tmp = config_get_option(conf, MAIN_NAME, "msg_level");
	if (tmp) {
		if (!strcmp(tmp, "fatal")) {
			msg_setlevel(MSG_FATAL);
		} else if (!strcmp(tmp, "error")) {
			msg_setlevel(MSG_ERROR);
		} else if (!strcmp(tmp, "debug")) {
			msg_setlevel(MSG_DEBUG);
		} else if (!strcmp(tmp, "info")) {
			msg_setlevel(MSG_INFO);
		} else if (!strcmp(tmp, "stats")) {
			msg_setlevel(MSG_STATS);
		} else {
			msg(MSG_FATAL, "Unknown msg level ...");
		}
	}
	
	// do we want to periodically output statistics on dropped/received packets?
	tmp = config_get_option(conf, "MAIN_NAME", "packet_stats");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			print_stats_enabled = 1;
		}
	}

	msg(MSG_INFO, "%s is initializing ...", argv[2]);

	pcap_file = config_get_option(conf, MAIN_NAME, "pcapfile");
	capture_interface = config_get_option(conf, MAIN_NAME, "interface");

	if (!pcap_file && !capture_interface) {
		msg(MSG_FATAL, "main: Neither \"pcapfile\" nor \"interface\" given in config file.");
		exit(-1);
	} if (pcap_file && capture_interface) {
		msg(MSG_FATAL, "main: Got \'pcapfile\" *and* \"interface\". Please decide whether you want to work on- or offline!");
		exit(-1);
	}

	tmp = config_get_option(conf, MAIN_NAME, "max_packet_size");
	if (tmp) {
		snaplen = atoi(tmp);
	}

	tmp = config_get_option(conf, MAIN_NAME, "packet_pool");
	if (tmp) {
		packet_pool_size = atoi(tmp);
	}

	// init connection pool
	if (!config_get_option(conf, MAIN_NAME, "init_connection_pool")) {
		msg(MSG_ERROR, "main: \"init_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_no = atoi(config_get_option(conf, MAIN_NAME, "init_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "max_connection_pool")) {
		msg(MSG_ERROR, "main: \"max_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_max = atoi(config_get_option(conf, MAIN_NAME, "max_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "flow_timeout")) {
		msg(MSG_ERROR, "main: \"flow_timeout\" missing in section %s", MAIN_NAME);
		return -1;
	}
	flow_timeout = atoi(config_get_option(conf, MAIN_NAME, "flow_timeout"));

	connection_init_pool(conn_no, conn_max, flow_timeout);


	struct packet_pool* packet_pool = packet_pool_init(packet_pool_size, snaplen);
	struct thread_data worker_data;
	worker_data.pool = packet_pool;
	worker_data.dumpers = &dumps;

	pcap_t* pfile;
	if (pcap_file) { 
		pfile = open_pcap(pcap_file, 0, snaplen); 
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
	} else {
		is_live = 1;
		pfile = open_pcap(capture_interface, 1, snaplen);
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		// the dumper creating can take a significant amount of time.
		// We could not read any packets during this initialization phase and 
		// could therefore drop a significant amount of packets (depending on
		// the link speed). We therefore close and reopen the pcap descriptor
		// in order to reset the statistics and get more accurate packet
		// drop statistice (we had to open the pcap interface for retrieving the
		// interface link type which is important for module initialization
		pcap_close(pfile);
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
		pfile = open_pcap(capture_interface, 1, snaplen);
	}
	msg(MSG_INFO, "%s is up and running. Starting to consume packets ...", argv[0]);

	struct pcap_pkthdr pcap_hdr;
	time_t last_stats = 0;
	time_t stats_interval = 10;
	uint64_t captured = 0;
	const unsigned char* data = NULL;
	while (running) {
		if (NULL != (data = pcap_next(pfile, &pcap_hdr))) {
			captured++;
			if (print_stats_enabled) {
				if (pcap_hdr.ts.tv_sec - last_stats > stats_interval && is_live) {
					last_stats = pcap_hdr.ts.tv_sec;
					print_stats(pfile, captured, packet_pool);
				}
			}
			packet_new(packet_pool, &pcap_hdr, data);
		} else {
			if (!is_live)
				running = 0;
		}
	}

	msg(MSG_INFO, "%s finished reading packets ...", argv[0]);

	// TODO: this is a hack! we might need to wake the worker thread
	// because it might be blocked at a mutex waiting for new packets
	// we have to insert a packet in order to wake the thread from the 
	// mutex. Hence, we re-include the last packet into the pool again ...
	// FIXME: The hack can result in a segmentation fault if no packet
	// has been read from the pcap_t ...
	unsigned char* useless = malloc(snaplen);
	packet_new(packet_pool, &pcap_hdr, useless);
	free(useless);
	pthread_join(worker_id, NULL);

	// ok, the second worker is stopped right now
	// we are therefore the only thread that works on the connection pool.
	// lets timeout all active connnections to update the statistics (e.g. for stats_module)
	connection_flush_all_active_conns();

	dumpers_finish(&dumps);
	connection_deinit_pool();
	packet_pool_deinit(packet_pool);
	config_free(conf);

	return 0;
}
Exemple #20
0
static void parse_options(int argc, char **argv, ui_driver_t **ui_driver, cl_options_t *cl_options) {
	int c;

#ifdef HAVE_GETOPT_LONG

	int optindex;

	struct option options[] = {{"help", no_argument, NULL, 'h'},
							   {"fullscreen", no_argument, NULL, 'f'},
							   {"width", required_argument, NULL, 'W'},
							   {"height", required_argument, NULL, 'H'},
							   {"1st-engine", required_argument, NULL, '1'},
							   {0, 0, 0, 0}};

	/* On macOS (under certain circumstances) a process serial number will be passed in. In this
	 * case we skip parsing the command line options.
	 */ 
	if (argc > 1 && strncmp(argv[1], "-psn_", 5) == 0) {
		DBG_WARN("Received '%s'; ignoring all command line arguments", argv[1]);
		return;
	}

	while ((c = getopt_long(argc, argv, "1:fhW:H:", options, &optindex)) > -1) {
#else

	while ((c = getopt(argc, argv, "1:fhW:H:")) > -1) {
#endif /* HAVE_GETOPT_LONG */
		switch (c) {
		case 'h':
			printf("Usage: dreamchess [options]\n\n"
				   "An xboard-compatible chess interface.\n\n"
				   "Options:\n"
                   OPTION_TEXT("--help\t", "-h\t", "show help")
				   OPTION_TEXT("--fullscreen\t", "-f\t", "run fullscreen")
				   OPTION_TEXT("--width\t", "-W<num>", "set screen width")
				   OPTION_TEXT("--height\t", "-H<num>", "set screen height")
				   OPTION_TEXT("--1st-engine <eng>", "-1<eng>", "use <eng> as first chess engine")
				   OPTION_TEXT("\t\t", "\t", "  defaults to 'dreamer'"));
			exit(0);
		case '1':
			cl_options->engine = optarg;
			break;
		case 'f':
			cl_options->fs = 1;
			break;
		case 'W':
			cl_options->width = atoi(optarg);
			break;
		case 'H':
			cl_options->height = atoi(optarg);
		}
	}
}

static void set_cl_options(cl_options_t *cl_options) {
	option_t *option;

	if (cl_options->engine) {
		option = config_get_option("first_engine");
		option_string_set_text(option, cl_options->engine);
	}

	if (cl_options->fs) {
		option = config_get_option("full_screen");
		option_select_value_by_name(option, "On");
	}

	if (cl_options->width) {
		option = config_get_option("custom_resolution_width");
		option->value = cl_options->width;
		option = config_get_option("resolution");
		option_select_value_by_name(option, "Custom");
	}

	if (cl_options->height) {
		option = config_get_option("custom_resolution_height");
		option->value = cl_options->height;
		option = config_get_option("resolution");
		option_select_value_by_name(option, "Custom");
	}
}