/* 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; }
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; }