Example #1
0
/* Verifies data for New & Properties dialogs.
 * Returns: FALSE if the user needs to change any data. */
static gboolean update_config(const PropertyDialogElements *e, gboolean new_project)
{
	const gchar *name, *file_name, *base_path;
	gchar *locale_filename;
	gsize name_len;
	gint err_code = 0;
	GeanyProject *p;

	g_return_val_if_fail(e != NULL, TRUE);

	name = gtk_entry_get_text(GTK_ENTRY(e->name));
	name_len = strlen(name);
	if (name_len == 0)
	{
		SHOW_ERR(_("The specified project name is too short."));
		gtk_widget_grab_focus(e->name);
		return FALSE;
	}
	else if (name_len > MAX_NAME_LEN)
	{
		SHOW_ERR1(_("The specified project name is too long (max. %d characters)."), MAX_NAME_LEN);
		gtk_widget_grab_focus(e->name);
		return FALSE;
	}

	if (new_project)
		file_name = gtk_entry_get_text(GTK_ENTRY(e->file_name));
	else
		file_name = gtk_label_get_text(GTK_LABEL(e->file_name));

	if (G_UNLIKELY(! NZV(file_name)))
	{
		SHOW_ERR(_("You have specified an invalid project filename."));
		gtk_widget_grab_focus(e->file_name);
		return FALSE;
	}

	locale_filename = utils_get_locale_from_utf8(file_name);
	base_path = gtk_entry_get_text(GTK_ENTRY(e->base_path));
	if (NZV(base_path))
	{	/* check whether the given directory actually exists */
		gchar *locale_path = utils_get_locale_from_utf8(base_path);

		if (! g_path_is_absolute(locale_path))
		{	/* relative base path, so add base dir of project file name */
			gchar *dir = g_path_get_dirname(locale_filename);
			SETPTR(locale_path, g_strconcat(dir, G_DIR_SEPARATOR_S, locale_path, NULL));
			g_free(dir);
		}

		if (! g_file_test(locale_path, G_FILE_TEST_IS_DIR))
		{
			gboolean create_dir;

			create_dir = dialogs_show_question_full(NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL,
				_("Create the project's base path directory?"),
				_("The path \"%s\" does not exist."),
				base_path);

			if (create_dir)
				err_code = utils_mkdir(locale_path, TRUE);

			if (! create_dir || err_code != 0)
			{
				if (err_code != 0)
					SHOW_ERR1(_("Project base directory could not be created (%s)."),
						g_strerror(err_code));
				gtk_widget_grab_focus(e->base_path);
				utils_free_pointers(2, locale_path, locale_filename, NULL);
				return FALSE;
			}
		}
		g_free(locale_path);
	}
	/* finally test whether the given project file can be written */
	if ((err_code = utils_is_file_writable(locale_filename)) != 0 ||
		(err_code = g_file_test(locale_filename, G_FILE_TEST_IS_DIR) ? EISDIR : 0) != 0)
	{
		SHOW_ERR1(_("Project file could not be written (%s)."), g_strerror(err_code));
		gtk_widget_grab_focus(e->file_name);
		g_free(locale_filename);
		return FALSE;
	}
	g_free(locale_filename);

	if (app->project == NULL)
	{
		create_project();
		new_project = TRUE;
	}
	p = app->project;

	SETPTR(p->name, g_strdup(name));
	SETPTR(p->file_name, g_strdup(file_name));
	/* use "." if base_path is empty */
	SETPTR(p->base_path, g_strdup(NZV(base_path) ? base_path : "./"));

	if (! new_project)	/* save properties specific fields */
	{
		GtkTextIter start, end;
		GtkTextBuffer *buffer;
		GeanyDocument *doc = document_get_current();
		GeanyBuildCommand *oldvalue;
		GeanyFiletype *ft = doc ? doc->file_type : NULL;
		GtkWidget *widget;
		gchar *tmp;
		GString *str;
		GSList *node;

		/* get and set the project description */
		buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->description));
		gtk_text_buffer_get_start_iter(buffer, &start);
		gtk_text_buffer_get_end_iter(buffer, &end);
		SETPTR(p->description, g_strdup(gtk_text_buffer_get_text(buffer, &start, &end, FALSE)));

		foreach_slist(node, stash_groups)
			stash_group_update(node->data, e->dialog);

		/* read the project build menu */
		oldvalue = ft ? ft->projfilecmds : NULL;
		build_read_project(ft, e->build_properties);

		if (ft != NULL && ft->projfilecmds != oldvalue && ft->project_list_entry < 0)
		{
			if (p->build_filetypes_list == NULL)
				p->build_filetypes_list = g_ptr_array_new();
			ft->project_list_entry = p->build_filetypes_list->len;
			g_ptr_array_add(p->build_filetypes_list, ft);
		}
		build_menu_update(doc);

		widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled_project");
		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
			p->long_line_behaviour = 0;
		else
		{
			widget = ui_lookup_widget(e->dialog, "radio_long_line_default_project");
			if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
				p->long_line_behaviour = 1;
			else
				/* "Custom" radio button must be checked */
				p->long_line_behaviour = 2;
		}

		widget = ui_lookup_widget(e->dialog, "spin_long_line_project");
		p->long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
		apply_editor_prefs();

		/* get and set the project file patterns */
		tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(e->patterns)));
		g_strfreev(p->file_patterns);
		g_strstrip(tmp);
		str = g_string_new(tmp);
		do {} while (utils_string_replace_all(str, "  ", " "));
		p->file_patterns = g_strsplit(str->str, " ", -1);
		g_string_free(str, TRUE);
		g_free(tmp);
	}

	update_ui();

	return TRUE;
}
Example #2
0
static gint socket_fd_open_unix(const gchar *path)
{
	gint sock;
	struct sockaddr_un addr;
	gint val;
	gchar *real_path;

	sock = socket(PF_UNIX, SOCK_STREAM, 0);
	if (sock < 0)
	{
		log_error("Failed to create IPC socket", errno);
		return -1;
	}

	val = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
	{
		log_error("Failed to set IPC socket option", errno);
		socket_fd_close(sock);
		return -1;
	}

	/* fix for #1888561:
	 * in case the configuration directory is located on a network file system or any other
	 * file system which doesn't support sockets, we just link the socket there and create the
	 * real socket in the system's tmp directory assuming it supports sockets */
	real_path = g_strdup_printf("%s%cgeany_socket.%08x",
		g_get_tmp_dir(), G_DIR_SEPARATOR, g_random_int());

	if (utils_is_file_writable(real_path) != 0)
	{	/* if real_path is not writable for us, fall back to ~/.config/geany/geany_socket_*_* */
		/* instead of creating a symlink and print a warning */
		g_warning("Socket %s could not be written, using %s as fallback.", real_path, path);
		SETPTR(real_path, g_strdup(path));
	}
	/* create a symlink in e.g. ~/.config/geany/geany_socket_hostname__0 to /tmp/geany_socket.499602d2 */
	else if (symlink(real_path, path) != 0)
	{
		gint saved_errno = errno;
		gchar* message = g_strdup_printf(
			"Failed to create IPC socket symlink %s -> %s)",
			real_path,
			path);
		log_error(message, saved_errno);
		g_free(message);
		socket_fd_close(sock);
		return -1;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, real_path, sizeof(addr.sun_path) - 1);

	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		gint saved_errno = errno;
		gchar* message = g_strdup_printf("Failed to bind IPC socket (%s)", real_path);
		log_error(message, saved_errno);
		g_free(message);
		socket_fd_close(sock);
		return -1;
	}

	if (listen(sock, 1) < 0)
	{
		gint saved_errno = errno;
		gchar* message = g_strdup_printf("Failed to listen on IPC socket (%s)", real_path);
		log_error(message, saved_errno);
		g_free(message);
		socket_fd_close(sock);
		return -1;
	}

	g_chmod(real_path, 0600);

	g_free(real_path);

	return sock;
}