void test_setlocale() { GKeyFile *keyfile; gchar *value; gchar **list; gchar *input_list[2] = {"test2","test3"}; gsize length = 2; const gchar *data = "[1]\n" "key1=123\n" "key2=456\n"; keyfile = load_data (data, 0); g_key_file_set_locale_string(keyfile,"1","key3","C","test"); value = g_key_file_get_locale_string(keyfile,"1","key3","C",NULL); g_assert(!strcmp(value,"test")); g_free(value); value = g_key_file_get_locale_string(keyfile,"1","key3","de",NULL); g_assert(value == NULL); g_key_file_set_locale_string_list(keyfile,"1","key4","C",input_list,2); list = g_key_file_get_locale_string_list(keyfile,"1","key4","C",&length,NULL); g_assert(!strcmp(list[0],"test2")); g_assert(!strcmp(list[1],"test3")); }
static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data ); int match = 1; if ( tokens ) { for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) { int test = 0; GRegex *ftokens[2] = { tokens[j], NULL }; // Match name if ( rmpd->entry_list[index].name && helper_token_match ( ftokens, rmpd->entry_list[index].name ) ) { test = 1; } // Match generic name if ( !test && rmpd->entry_list[index].generic_name && helper_token_match ( ftokens, rmpd->entry_list[index].generic_name ) ) { test = 1; } // Match executable name. if ( !test && helper_token_match ( ftokens, rmpd->entry_list[index].exec ) ) { test = 1; } // Match against category. if ( !test ) { #ifdef GET_CAT_PARSE_TIME gchar **list = rmpd->entry_list[index].categories; for ( int iter = 0; !test && list && list[iter]; iter++ ) { test = helper_token_match ( ftokens, list[iter] ); } #else gchar **list = g_key_file_get_locale_string_list ( rmpd->entry_list[index].key_file, "Desktop Entry", "Categories", NULL, NULL, NULL ); for ( int iter = 0; !test && list && list[iter]; iter++ ) { test = helper_token_match ( ftokens, list[iter] ); } g_strfreev ( list ); #endif } if ( test == 0 ) { match = 0; } } } return match; }
/** * as_app_parse_file_key: **/ static gboolean as_app_parse_file_key (AsApp *app, GKeyFile *kf, const gchar *key, AsAppParseFlags flags, GError **error) { gchar *dot = NULL; guint i; guint j; g_autofree gchar *locale = NULL; g_autofree gchar *tmp = NULL; g_auto(GStrv) list = NULL; /* NoDisplay */ if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && strcasecmp (tmp, "True") == 0) as_app_add_veto (app, "NoDisplay=true"); /* Type */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (g_strcmp0 (tmp, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) { g_set_error_literal (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "not an application"); return FALSE; } /* Icon */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_name (icon, tmp); dot = g_strstr_len (tmp, -1, "."); if (dot != NULL) *dot = '\0'; if (as_utils_is_stock_icon_name (tmp)) { as_icon_set_name (icon, tmp); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); } else if ((flags & AS_APP_PARSE_FLAG_USE_FALLBACKS) > 0 && _as_utils_is_stock_icon_name_fallback (tmp)) { as_icon_set_name (icon, tmp); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); } else { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); } as_app_add_icon (app, icon); } /* Categories */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { /* not a standard category */ if (g_str_has_prefix (list[i], "X-")) continue; /* check the category is valid */ if (!as_utils_is_category_id (list[i])) continue; /* ignore some useless keys */ if (g_strcmp0 (list[i], "GTK") == 0) continue; if (g_strcmp0 (list[i], "Qt") == 0) continue; if (g_strcmp0 (list[i], "KDE") == 0) continue; if (g_strcmp0 (list[i], "GNOME") == 0) continue; as_app_add_category (app, list[i]); } } else if (g_strcmp0 (key, "Keywords") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, "C", kw_split[j]); } } } else if (g_str_has_prefix (key, "Keywords")) { locale = as_app_desktop_key_get_locale (key); list = g_key_file_get_locale_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, locale, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, locale, kw_split[j]); } } } else if (g_strcmp0 (key, "MimeType") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) as_app_add_mimetype (app, list[i]); } else if (g_strcmp0 (key, "X-AppInstall-Package") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_add_pkgname (app, tmp); /* OnlyShowIn */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) { /* if an app has only one entry, it's that desktop */ list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); if (g_strv_length (list) == 1) as_app_set_project_group (app, list[0]); /* Name */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || g_strcmp0 (key, "_Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); /* Name[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); /* Comment */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0 || g_strcmp0 (key, "_Comment") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, "C", tmp); /* Comment[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, locale, tmp); /* non-standard */ } else if (g_strcmp0 (key, "X-Ubuntu-Software-Center-Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); } else if (g_str_has_prefix (key, "X-Ubuntu-Software-Center-Name")) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Software-Center-Name", locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); } return TRUE; }
static void process_desktop_file (ProcessApplicationData *data, GFileInfo *file_info, GError **error) { TrackerSparqlBuilder *sparql; GKeyFile *key_file; gchar *name = NULL; gchar *path; gchar *type; gchar *filename; gchar *uri = NULL; GStrv cats; gsize cats_len; gboolean is_software = TRUE; const gchar *parent_urn; gchar *lang; #ifdef HAVE_MEEGOTOUCH gchar *logical_id = NULL; gchar *translation_catalog = NULL; #endif /* HAVE_MEEGOTOUCH */ sparql = data->sparql; key_file = data->key_file; type = data->type; path = g_file_get_path (data->file); /* Retrieve LANG locale setup */ lang = tracker_locale_get (TRACKER_LOCALE_LANGUAGE); /* Try to get the categories with our desired LANG locale... */ cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", lang, &cats_len, NULL); if (!cats) { /* If our desired locale failed, use the list of LANG locales prepared by GLib * (will return untranslated string if none of the locales available) */ cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", NULL, &cats_len, NULL); } /* NOTE: We sanitize categories later on when iterating them */ #ifdef HAVE_MEEGOTOUCH /* If defined, start with the logical strings */ logical_id = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "X-MeeGo-Logical-Id", NULL); translation_catalog = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "X-MeeGo-Translation-Catalog", NULL); if (logical_id && translation_catalog) { name = tracker_meego_translate (translation_catalog, logical_id); } g_free (logical_id); g_free (translation_catalog); #endif /* HAVE_MEEGOTOUCH */ if (!name) { /* Try to get the name with our desired LANG locale... */ name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", lang, NULL); if (!name) { /* If our desired locale failed, use the list of LANG locales prepared by GLib * (will return untranslated string if none of the locales available) */ name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL, NULL); } } /* Sanitize name */ if (name) { g_strstrip (name); } if (name && g_ascii_strcasecmp (type, "Directory") == 0) { gchar *canonical_uri = tracker_sparql_escape_uri_printf (SOFTWARE_CATEGORY_URN_PREFIX "%s", path); gchar *icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL); uri = canonical_uri; tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory"); if (icon) { gchar *escaped_icon; gchar *icon_uri; /* Sanitize icon */ g_strstrip (icon); escaped_icon = g_uri_escape_string (icon, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE); icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", escaped_icon); tracker_sparql_builder_subject_iri (sparql, icon_uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:Image"); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "nfo:softwareCategoryIcon"); tracker_sparql_builder_object_iri (sparql, icon_uri); g_free (icon_uri); g_free (escaped_icon); g_free (icon); } is_software = FALSE; } else if (name && g_ascii_strcasecmp (type, "Application") == 0) { uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nie:DataSource"); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication"); tracker_sparql_builder_object (sparql, "nie:DataObject"); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN); } else if (name && g_ascii_strcasecmp (type, "Link") == 0) { gchar *url = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "URL", NULL); if (url) { uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:Bookmark"); tracker_sparql_builder_predicate (sparql, "nfo:bookmarks"); tracker_sparql_builder_object_iri (sparql, url); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN); is_software = FALSE; g_free (url); } else { g_warning ("Invalid desktop file: '%s'", uri); g_warning (" Type 'Link' requires a URL"); } #ifdef HAVE_MEEGOTOUCH } else if (name && g_ascii_strcasecmp (type, "ControlPanelApplet") == 0) { /* Special case control panel applets */ /* The URI of the InformationElement should be a UUID URN */ uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nie:DataSource"); /* TODO This is atm specific for Maemo */ tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "maemo:ControlPanelApplet"); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLET_DATASOURCE_URN); /* This matches SomeApplet as Type= */ } else if (name && g_str_has_suffix (type, "Applet")) { /* The URI of the InformationElement should be a UUID URN */ uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nie:DataSource"); /* TODO This is atm specific for Maemo */ tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "maemo:SoftwareApplet"); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLET_DATASOURCE_URN); } else if (name && g_ascii_strcasecmp (type, "DUIApplication") == 0) { uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nie:DataSource"); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication"); tracker_sparql_builder_object (sparql, "nie:DataObject"); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN); #endif /* HAVE_MEEGOTOUCH */ } else { /* Invalid type, all valid types are already listed above */ uri = g_file_get_uri (data->file); tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN); tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nie:DataSource"); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication"); tracker_sparql_builder_object (sparql, "nie:DataObject"); tracker_sparql_builder_predicate (sparql, "nie:dataSource"); tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN); if (name) { /* If we got a name, then the issue comes from the type. * As we're defaulting to Application here, we just g_debug() the problem. */ g_debug ("Invalid desktop file: '%s'", uri); g_debug (" Type '%s' is not part of the desktop file specification (expected 'Application', 'Link' or 'Directory')", type); g_debug (" Defaulting to 'Application'"); } else { /* If we didn't get a name, the problem is more severe as we don't default it * to anything, so we g_warning() it. */ g_warning ("Invalid desktop file: '%s'", uri); #ifdef HAVE_MEEGOTOUCH g_warning (" Couldn't get name, missing or wrong key (X-MeeGo-Logical-Id, X-MeeGo-Translation-Catalog or Name)"); #else g_warning (" Couldn't get name, missing key (Name)"); #endif } } if (sparql && uri) { gchar *desktop_file_uri; tracker_sparql_builder_predicate (sparql, "a"); if (is_software) { tracker_sparql_builder_object (sparql, "nfo:Executable"); } tracker_sparql_builder_object (sparql, "nfo:FileDataObject"); tracker_sparql_builder_object (sparql, "nie:DataObject"); /* Apparently this gets added by the file-module ATM tracker_sparql_builder_predicate (sparql, "tracker:available"); tracker_sparql_builder_object_boolean (sparql, TRUE); */ /* We should always always have a proper name if the desktop file is correct * w.r.t to the Meego or Freedesktop specs, but sometimes this is not true, * so instead of passing wrong stuff to the SPARQL builder, we avoid it. * If we don't have a proper name, we already warned it before. */ if (name) { tracker_sparql_builder_predicate (sparql, "nie:title"); tracker_sparql_builder_object_string (sparql, name); } if (is_software) { gchar *icon; insert_data_from_desktop_file (sparql, uri, TRACKER_PREFIX_NIE "comment", key_file, "Comment", lang); insert_data_from_desktop_file (sparql, uri, TRACKER_PREFIX_NFO "softwareCmdLine", key_file, "Exec", lang); icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL); if (icon) { gchar *escaped_icon; gchar *icon_uri; /* Sanitize icon */ g_strstrip (icon); escaped_icon = g_uri_escape_string (icon, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE); icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", escaped_icon); tracker_sparql_builder_subject_iri (sparql, icon_uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:Image"); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "nfo:softwareIcon"); tracker_sparql_builder_object_iri (sparql, icon_uri); g_free (icon_uri); g_free (escaped_icon); g_free (icon); } } if (cats) { gsize i; for (i = 0 ; cats[i] && i < cats_len ; i++) { gchar *cat_uri; gchar *cat; cat = cats[i]; if (!cat) { continue; } /* Sanitize category */ g_strstrip (cat); cat_uri = tracker_sparql_escape_uri_printf (SOFTWARE_CATEGORY_URN_PREFIX "%s", cat); /* There are also .desktop * files that describe these categories, but we can handle * preemptively creating them if we visit a app .desktop * file that mentions one that we don't yet know about */ tracker_sparql_builder_subject_iri (sparql, cat_uri); tracker_sparql_builder_predicate (sparql, "a"); tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory"); tracker_sparql_builder_predicate (sparql, "nie:title"); tracker_sparql_builder_object_string (sparql, cat); tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "nie:isLogicalPartOf"); tracker_sparql_builder_object_iri (sparql, cat_uri); g_free (cat_uri); } } filename = g_filename_display_basename (path); tracker_sparql_builder_predicate (sparql, "nfo:fileName"); tracker_sparql_builder_object_string (sparql, filename); g_free (filename); /* The URL of the DataObject */ desktop_file_uri = g_file_get_uri (data->file); tracker_sparql_builder_predicate (sparql, "nie:url"); tracker_sparql_builder_object_string (sparql, desktop_file_uri); /* Laying the link between the IE and the DO */ tracker_sparql_builder_subject_iri (sparql, uri); tracker_sparql_builder_predicate (sparql, "nie:isStoredAs"); tracker_sparql_builder_object_iri (sparql, desktop_file_uri); g_free (desktop_file_uri); } if (file_info) { guint64 time; time = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED); tracker_sparql_builder_predicate (sparql, "nfo:fileLastModified"); tracker_sparql_builder_object_date (sparql, (time_t *) &time); } parent_urn = tracker_miner_fs_get_parent_urn (TRACKER_MINER_FS (data->miner), data->file); if (parent_urn) { tracker_sparql_builder_predicate (sparql, "nfo:belongsToContainer"); tracker_sparql_builder_object_iri (sparql, parent_urn); } tracker_sparql_builder_insert_close (sparql); g_strfreev (cats); g_free (uri); g_free (path); g_free (name); g_free (lang); }
static void exec_cmd_entry ( DRunModeEntry *e ) { GError *error = NULL; GRegex *reg = g_regex_new ( "%[a-zA-Z]", 0, 0, &error ); if ( error != NULL ) { g_warning ( "Internal error, failed to create regex: %s.", error->message ); g_error_free ( error ); return; } struct RegexEvalArg earg = { .e = e, .success = TRUE }; char *str = g_regex_replace_eval ( reg, e->exec, -1, 0, 0, drun_helper_eval_cb, &earg, &error ); if ( error != NULL ) { g_warning ( "Internal error, failed replace field codes: %s.", error->message ); g_error_free ( error ); return; } g_regex_unref ( reg ); if ( earg.success == FALSE ) { g_warning ( "Invalid field code in Exec line: %s.", e->exec );; return; } if ( str == NULL ) { g_warning ( "Nothing to execute after processing: %s.", e->exec );; return; } const gchar *fp = g_strstrip ( str ); gchar *exec_path = g_key_file_get_string ( e->key_file, "Desktop Entry", "Path", NULL ); if ( exec_path != NULL && strlen ( exec_path ) == 0 ) { // If it is empty, ignore this property. (#529) g_free ( exec_path ); exec_path = NULL; } RofiHelperExecuteContext context = { .name = e->name, .icon = e->icon_name, .app_id = e->app_id, }; gboolean sn = g_key_file_get_boolean ( e->key_file, "Desktop Entry", "StartupNotify", NULL ); gchar *wmclass = NULL; if ( sn && g_key_file_has_key ( e->key_file, "Desktop Entry", "StartupWMClass", NULL ) ) { context.wmclass = wmclass = g_key_file_get_string ( e->key_file, "Desktop Entry", "StartupWMClass", NULL ); } // Returns false if not found, if key not found, we don't want run in terminal. gboolean terminal = g_key_file_get_boolean ( e->key_file, "Desktop Entry", "Terminal", NULL ); if ( helper_execute_command ( exec_path, fp, terminal, sn ? &context : NULL ) ) { char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL ); char *key = g_strdup_printf ( "%s:::%s", e->root, e->path ); history_set ( path, key ); g_free ( key ); g_free ( path ); } g_free ( wmclass ); g_free ( exec_path ); g_free ( str ); } /** * This function absorbs/freeś path, so this is no longer available afterwards. */ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path, const gchar *basename ) { // Create ID on stack. // We know strlen (path ) > strlen(root)+1 const ssize_t id_len = strlen ( path ) - strlen ( root ); char id[id_len]; g_strlcpy ( id, &( path[strlen ( root ) + 1] ), id_len ); for ( int index = 0; index < id_len; index++ ) { if ( id[index] == '/' ) { id[index] = '-'; } } // Check if item is on disabled list. if ( g_hash_table_contains ( pd->disabled_entries, id ) ) { g_debug ( "Skipping: %s, was previously seen.", id ); return TRUE; } GKeyFile *kf = g_key_file_new (); GError *error = NULL; g_key_file_load_from_file ( kf, path, 0, &error ); // If error, skip to next entry if ( error != NULL ) { g_debug ( "Failed to parse desktop file: %s because: %s", path, error->message ); g_error_free ( error ); g_key_file_free ( kf ); return FALSE; } // Skip non Application entries. gchar *key = g_key_file_get_string ( kf, "Desktop Entry", "Type", NULL ); if ( key == NULL ) { // No type? ignore. g_debug ( "Skipping desktop file: %s because: No type indicated", path ); g_key_file_free ( kf ); return FALSE; } if ( g_strcmp0 ( key, "Application" ) ) { g_debug ( "Skipping desktop file: %s because: Not of type application (%s)", path, key ); g_free ( key ); g_key_file_free ( kf ); return FALSE; } g_free ( key ); // Name key is required. if ( !g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) { g_debug ( "Invalid DesktopFile: '%s', no 'Name' key present.", path ); g_key_file_free ( kf ); return FALSE; } // Skip hidden entries. if ( g_key_file_get_boolean ( kf, "Desktop Entry", "Hidden", NULL ) ) { g_debug ( "Adding desktop file: %s to disabled list because: Hdden", path ); g_key_file_free ( kf ); g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); return FALSE; } // Skip entries that have NoDisplay set. if ( g_key_file_get_boolean ( kf, "Desktop Entry", "NoDisplay", NULL ) ) { g_debug ( "Adding desktop file: %s to disabled list because: NoDisplay", path ); g_key_file_free ( kf ); g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); return FALSE; } // We need Exec, don't support DBusActivatable if ( !g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) { g_debug ( "Unsupported DesktopFile: '%s', no 'Exec' key present.", path ); g_key_file_free ( kf ); return FALSE; } if ( g_key_file_has_key ( kf, "Desktop Entry", "TryExec", NULL ) ) { char *te = g_key_file_get_string ( kf, "Desktop Entry", "TryExec", NULL ); if ( !g_path_is_absolute ( te ) ) { char *fp = g_find_program_in_path ( te ); if ( fp == NULL ) { g_free ( te ); g_key_file_free ( kf ); return FALSE; } g_free ( fp ); } else { if ( g_file_test ( te, G_FILE_TEST_IS_EXECUTABLE ) == FALSE ) { g_free ( te ); g_key_file_free ( kf ); return FALSE; } } g_free ( te ); } size_t nl = ( ( pd->cmd_list_length ) + 1 ); if ( nl >= pd->cmd_list_length_actual ) { pd->cmd_list_length_actual += 256; pd->entry_list = g_realloc ( pd->entry_list, pd->cmd_list_length_actual * sizeof ( *( pd->entry_list ) ) ); } pd->entry_list[pd->cmd_list_length].icon_size = 0; pd->entry_list[pd->cmd_list_length].root = g_strdup ( root ); pd->entry_list[pd->cmd_list_length].path = g_strdup ( path ); pd->entry_list[pd->cmd_list_length].app_id = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) ); gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL ); pd->entry_list[pd->cmd_list_length].name = n; gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL ); pd->entry_list[pd->cmd_list_length].generic_name = gn; pd->entry_list[pd->cmd_list_length].categories = g_key_file_get_locale_string_list ( kf, "Desktop Entry", "Categories", NULL, NULL, NULL ); pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, "Desktop Entry", "Exec", NULL ); if ( config.show_icons ) { pd->entry_list[pd->cmd_list_length].icon_name = g_key_file_get_locale_string ( kf, "Desktop Entry", "Icon", NULL, NULL ); } else{ pd->entry_list[pd->cmd_list_length].icon_name = NULL; } pd->entry_list[pd->cmd_list_length].icon = NULL; // Keep keyfile around. pd->entry_list[pd->cmd_list_length].key_file = kf; // We don't want to parse items with this id anymore. g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); ( pd->cmd_list_length )++; return TRUE; } /** * Internal spider used to get list of executables. */ static void walk_dir ( DRunModePrivateData *pd, const char *root, const char *dirname ) { DIR *dir; g_debug ( "Checking directory %s for desktop files.", dirname ); dir = opendir ( dirname ); if ( dir == NULL ) { return; } struct dirent *file; gchar *filename = NULL; struct stat st; while ( ( file = readdir ( dir ) ) != NULL ) { if ( file->d_name[0] == '.' ) { continue; } switch ( file->d_type ) { case DT_LNK: case DT_REG: case DT_DIR: case DT_UNKNOWN: filename = g_build_filename ( dirname, file->d_name, NULL ); break; default: continue; } // On a link, or if FS does not support providing this information // Fallback to stat method. if ( file->d_type == DT_LNK || file->d_type == DT_UNKNOWN ) { file->d_type = DT_UNKNOWN; if ( stat ( filename, &st ) == 0 ) { if ( S_ISDIR ( st.st_mode ) ) { file->d_type = DT_DIR; } else if ( S_ISREG ( st.st_mode ) ) { file->d_type = DT_REG; } } } switch ( file->d_type ) { case DT_REG: // Skip files not ending on .desktop. if ( g_str_has_suffix ( file->d_name, ".desktop" ) ) { read_desktop_file ( pd, root, filename, file->d_name ); } break; case DT_DIR: walk_dir ( pd, root, filename ); break; default: break; } g_free ( filename ); } closedir ( dir ); }
/** * This function absorbs/freeś path, so this is no longer available afterwards. */ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path ) { // Create ID on stack. // We know strlen (path ) > strlen(root)+1 const ssize_t id_len = strlen ( path ) - strlen ( root ); char id[id_len]; g_strlcpy ( id, &( path[strlen ( root ) + 1] ), id_len ); for ( int index = 0; index < id_len; index++ ) { if ( id[index] == '/' ) { id[index] = '-'; } } // Check if item is on disabled list. if ( g_hash_table_contains ( pd->disabled_entries, id ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping: %s, was previously seen.", id ); return TRUE; } GKeyFile *kf = g_key_file_new (); GError *error = NULL; g_key_file_load_from_file ( kf, path, 0, &error ); // If error, skip to next entry if ( error != NULL ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Failed to parse desktop file: %s because: %s", path, error->message ); g_error_free ( error ); g_key_file_free ( kf ); return FALSE; } // Skip non Application entries. gchar *key = g_key_file_get_string ( kf, "Desktop Entry", "Type", NULL ); if ( key == NULL ) { // No type? ignore. g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping desktop file: %s because: No type indicated", path ); g_key_file_free ( kf ); return FALSE; } if ( g_strcmp0 ( key, "Application" ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping desktop file: %s because: Not of type application (%s)", path, key ); g_free ( key ); g_key_file_free ( kf ); return FALSE; } g_free ( key ); // Name key is required. if ( !g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Invalid DesktopFile: '%s', no 'Name' key present.\n", path ); g_key_file_free ( kf ); return FALSE; } // Skip hidden entries. if ( g_key_file_get_boolean ( kf, "Desktop Entry", "Hidden", NULL ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Adding desktop file: %s to disabled list because: Hdden", path ); g_key_file_free ( kf ); g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); return FALSE; } // Skip entries that have NoDisplay set. if ( g_key_file_get_boolean ( kf, "Desktop Entry", "NoDisplay", NULL ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Adding desktop file: %s to disabled list because: NoDisplay", path ); g_key_file_free ( kf ); g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); return FALSE; } // We need Exec, don't support DBusActivatable if ( !g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) { g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Unsupported DesktopFile: '%s', no 'Exec' key present.\n", path ); g_key_file_free ( kf ); return FALSE; } size_t nl = ( ( pd->cmd_list_length ) + 1 ); if ( nl >= pd->cmd_list_length_actual ) { pd->cmd_list_length_actual += 256; pd->entry_list = g_realloc ( pd->entry_list, pd->cmd_list_length_actual * sizeof ( *( pd->entry_list ) ) ); } pd->entry_list[pd->cmd_list_length].root = g_strdup ( root ); pd->entry_list[pd->cmd_list_length].path = g_strdup ( path ); gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL ); pd->entry_list[pd->cmd_list_length].name = n; gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL ); pd->entry_list[pd->cmd_list_length].generic_name = gn; #ifdef GET_CAT_PARSE_TIME pd->entry_list[pd->cmd_list_length].categories = g_key_file_get_locale_string_list ( kf, "Desktop Entry", "Categories", NULL, NULL, NULL ); #endif pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, "Desktop Entry", "Exec", NULL ); // Keep keyfile around. pd->entry_list[pd->cmd_list_length].key_file = kf; // We don't want to parse items with this id anymore. g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); ( pd->cmd_list_length )++; return TRUE; }
static gboolean as_app_parse_file_key (AsApp *app, GKeyFile *kf, const gchar *key, AsAppParseFlags flags, GError **error) { guint i; guint j; g_autofree gchar *locale = NULL; g_autofree gchar *tmp = NULL; g_auto(GStrv) list = NULL; /* NoDisplay */ if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && strcasecmp (tmp, "True") == 0) as_app_add_veto (app, "NoDisplay=true"); /* Type */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (g_strcmp0 (tmp, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) { g_set_error_literal (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "not an application"); return FALSE; } /* Icon */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') { g_autoptr(AsIcon) icon = NULL; icon = as_app_desktop_create_icon (app, tmp, flags); as_app_add_icon (app, icon); } /* Categories */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { const gchar *category_blacklist[] = { "X-GNOME-Settings-Panel", "X-Unity-Settings-Panel", NULL }; /* we have to veto these */ for (j = 0; category_blacklist[j] != NULL; j++) { if (g_strcmp0 (list[i], category_blacklist[j]) == 0) { as_app_add_veto (app, "Has category %s", category_blacklist[j]); } } /* check the category is valid */ if (!as_utils_is_category_id (list[i])) continue; /* ignore some useless keys */ if (g_strcmp0 (list[i], "GTK") == 0) continue; if (g_strcmp0 (list[i], "Qt") == 0) continue; if (g_strcmp0 (list[i], "KDE") == 0) continue; if (g_strcmp0 (list[i], "GNOME") == 0) continue; as_app_add_category (app, list[i]); } } else if (g_strcmp0 (key, "Keywords") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, "C", kw_split[j]); } } } else if (g_str_has_prefix (key, "Keywords")) { locale = as_app_desktop_key_get_locale (key); if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS && !g_strv_contains (g_get_language_names (), locale)) return TRUE; list = g_key_file_get_locale_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, locale, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, locale, kw_split[j]); } } } else if (g_strcmp0 (key, "MimeType") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) as_app_add_mimetype (app, list[i]); } else if (g_strcmp0 (key, "X-AppInstall-Package") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_add_pkgname (app, tmp); /* OnlyShowIn */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) { /* if an app has only one entry, it's that desktop */ list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); if (g_strv_length (list) == 1) as_app_set_project_group (app, list[0]); /* Name */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || g_strcmp0 (key, "_Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); /* Name[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) { locale = as_app_desktop_key_get_locale (key); if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS && !g_strv_contains (g_get_language_names (), locale)) return TRUE; tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); /* Comment */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0 || g_strcmp0 (key, "_Comment") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, "C", tmp); /* Comment[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) { locale = as_app_desktop_key_get_locale (key); if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS && !g_strv_contains (g_get_language_names (), locale)) return TRUE; tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, locale, tmp); /* non-standard */ } else if (g_strcmp0 (key, "X-Ubuntu-Software-Center-Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); } else if (g_str_has_prefix (key, "X-Ubuntu-Software-Center-Name")) { locale = as_app_desktop_key_get_locale (key); if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS && !g_strv_contains (g_get_language_names (), locale)) return TRUE; tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Software-Center-Name", locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); /* for Ubuntu */ } else if (g_strcmp0 (key, "X-AppStream-Ignore") == 0) { gboolean ret; ret = g_key_file_get_boolean (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (ret) as_app_add_veto (app, "X-AppStream-Ignore"); } /* add any external attribute as metadata to the application */ if (flags & AS_APP_PARSE_FLAG_ADD_ALL_METADATA) as_app_parse_file_metadata (app, kf, key); return TRUE; }
MetaData * restraint_parse_metadata (gchar *filename, gchar *locale, GError **error) { g_return_val_if_fail(error == NULL || *error == NULL, FALSE); GKeyFile *keyfile; GKeyFileFlags flags; GError *tmp_error = NULL; MetaData *metadata = g_slice_new0 (MetaData); /* Create a new GKeyFile object and a bitwise list of flags. */ keyfile = g_key_file_new(); /* This is not really needed since I don't envision writing the file back out */ flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; /* Load the GKeyFile from metadata or return. */ if (!g_key_file_load_from_file(keyfile, filename, flags, &tmp_error)) { g_propagate_error(error, tmp_error); goto error; } metadata->name = g_strstrip(g_key_file_get_locale_string(keyfile, "General", "name", locale, &tmp_error)); if (tmp_error != NULL && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); gchar *key_entry_point = g_key_file_get_locale_string(keyfile, "restraint", "entry_point", locale, &tmp_error); if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); if (key_entry_point != NULL) { metadata->entry_point = key_entry_point; } gchar *max_time = g_key_file_get_locale_string (keyfile, "restraint", "max_time", locale, &tmp_error); if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); if (max_time != NULL) { gint64 time = parse_time_string(max_time, &tmp_error); g_free(max_time); if (tmp_error) { g_propagate_error(error, tmp_error); goto error; } // If max_time is set it's because we read it from our run data metadata->max_time = time; } gsize length; gchar **dependencies = g_key_file_get_locale_string_list(keyfile, "restraint", "dependencies", locale, &length, &tmp_error); gchar **dependency = dependencies; if (dependency) { while (*dependency) { metadata->dependencies = g_slist_prepend (metadata->dependencies, g_strdup(*dependency)); dependency++; } g_strfreev (dependencies); } else metadata->dependencies = NULL; if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); gchar **softdependencies = g_key_file_get_locale_string_list(keyfile, "restraint", "softDependencies", locale, &length, &tmp_error); gchar **softdependency = softdependencies; if (softdependency) { while (*softdependency) { metadata->softdependencies = g_slist_prepend (metadata->softdependencies, g_strdup(*softdependency)); softdependency++; } g_strfreev (softdependencies); } else metadata->softdependencies = NULL; if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); gchar **repodeps = g_key_file_get_locale_string_list(keyfile, "restraint", "repoRequires", locale, &length, &tmp_error); gchar **repodep = repodeps; if (repodep) { while (*repodep) { metadata->repodeps = g_slist_prepend (metadata->repodeps, g_strdup(*repodep)); repodep++; } g_strfreev (repodeps); } else metadata->repodeps = NULL; if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); gchar **envvars = g_key_file_get_locale_string_list(keyfile, "restraint", "environment", locale, &length, &tmp_error); gchar **envvar = envvars; if (envvar) { while (*envvar) { gchar **split = g_strsplit(*envvar, "=", 2); if(split[0] != NULL && split[1] != NULL){ Param *p = restraint_param_new(); p->name = g_strdup(split[0]); p->value = g_strdup(split[1]); metadata->envvars = g_slist_prepend(metadata->envvars, p); } g_strfreev(split); envvar++; } g_strfreev(envvars); } else { metadata->envvars = NULL; } if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); metadata->nolocalwatchdog = g_key_file_get_boolean (keyfile, "restraint", "no_localwatchdog", &tmp_error); if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); metadata->use_pty = g_key_file_get_boolean (keyfile, "restraint", "use_pty", &tmp_error); if (tmp_error && tmp_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { g_propagate_error(error, tmp_error); goto error; } g_clear_error (&tmp_error); g_key_file_free(keyfile); return metadata; error: restraint_metadata_free(metadata); g_key_file_free(keyfile); return NULL; }