int read_desktop_file(const char *path, DesktopEntry *entry) { FILE *fp; char *line = NULL; size_t line_size; char *key, *value; int i; entry->name = entry->icon = entry->exec = NULL; if ((fp = fopen(path, "rt")) == NULL) { fprintf(stderr, "Could not open file %s\n", path); return 0; } gchar **languages = (gchar **)g_get_language_names(); // lang_index is the index of the language for the best Name key in the language vector // lang_index_default is a constant that encodes the Name key without a language int lang_index, lang_index_default; #define LANG_DBG 0 if (LANG_DBG) printf("Languages:"); for (i = 0; languages[i]; i++) { if (LANG_DBG) printf(" %s", languages[i]); } if (LANG_DBG) printf("\n"); lang_index_default = i; // we currently do not know about any Name key at all, so use an invalid index lang_index = lang_index_default + 1; int inside_desktop_entry = 0; while (getline(&line, &line_size, fp) >= 0) { int len = strlen(line); if (len == 0) continue; line[len - 1] = '\0'; if (line[0] == '[') { inside_desktop_entry = (strcmp(line, "[Desktop Entry]") == 0); } if (inside_desktop_entry && parse_dektop_line(line, &key, &value)) { if (strstr(key, "Name") == key) { if (strcmp(key, "Name") == 0 && lang_index > lang_index_default) { entry->name = strdup(value); lang_index = lang_index_default; } else { for (i = 0; languages[i] && i < lang_index; i++) { gchar *localized_key = g_strdup_printf("Name[%s]", languages[i]); if (strcmp(key, localized_key) == 0) { if (entry->name) free(entry->name); entry->name = strdup(value); lang_index = i; } g_free(localized_key); } } } else if (!entry->exec && strcmp(key, "Exec") == 0) { entry->exec = strdup(value); } else if (!entry->icon && strcmp(key, "Icon") == 0) { entry->icon = strdup(value); } } } fclose (fp); // From this point: // entry->name, entry->icon, entry->exec will never be empty strings (can be NULL though) expand_exec(entry, path); free(line); return 1; }
static int simple_run(active_db_h * service, process_h * process) { char *exec = NULL; char **argv = NULL; size_t argc = 0; int result = FALSE; char *argv0 = NULL; D_("service: %s process: %s.\n", service->name, process->pt->name); exec = (char *)get_string_var(&EXEC, process->pt->name, service); if (!exec) return FALSE; initng_string_fix_escapes(exec); /* argv-entries are pointer to exec_t[x] */ argv = initng_string_split_delim(exec, WHITESPACE, &argc); /* make sure we got something from the split */ if (!argv || !argv[0]) { if (argv) initng_string_split_delim_free(argv); D_("initng_string_split_delim on exec returns NULL.\n"); return FALSE; } /* if it not contains a full path */ if (argv[0][0] != '/') { argv0 = expand_exec(argv[0]); if (!argv0) { F_("SERVICE: %s %s -- %s was not found in search " "path.\n", service->name, process->pt->name, argv[0]); initng_string_split_delim_free(argv); argv = NULL; return FALSE; } free(argv[0]); argv[0] = argv0; /* Check this before freeing! */ } /* try to execute, remember the result */ result = simple_exec_fork(process, service, argc, argv); /* clean up */ /* First free the fixed argv0 if its not a plain link to argv[0] */ if (argv0 && argv0 != argv[0]) free(argv0); argv0 = NULL; // Later free the big argv array initng_string_split_delim_free(argv); argv = NULL; /* return result */ if (result == FAIL) return FALSE; return result; }