From 0b4499cdcde2614d2bd2a9e0a9dd8ac718367bc5 Mon Sep 17 00:00:00 2001 From: Damjan Jovanovic Date: Sat, 11 Apr 2009 10:10:59 +0200 Subject: [PATCH] winemenubuilder: Build freedesktop MIME type list for later use. --- programs/winemenubuilder/winemenubuilder.c | 169 +++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c index 9dafc16a13d..58e84c6acba 100644 --- a/programs/winemenubuilder/winemenubuilder.c +++ b/programs/winemenubuilder/winemenubuilder.c @@ -78,6 +78,7 @@ #include "wine/unicode.h" #include "wine/debug.h" #include "wine/library.h" +#include "wine/list.h" #include "wine.xpm" #ifdef HAVE_PNG_H @@ -144,6 +145,13 @@ typedef struct int nIndex; } ENUMRESSTRUCT; +struct xdg_mime_type +{ + char *mimeType; + char *glob; + struct list entry; +}; + static char *xdg_config_dir; static char *xdg_data_dir; static char *xdg_desktop_dir; @@ -1243,6 +1251,165 @@ static HRESULT get_cmdline( IShellLinkW *sl, LPWSTR szPath, DWORD pathSize, return hr; } +static BOOL next_line(FILE *file, char **line, int *size) +{ + int pos = 0; + char *cr; + if (*line == NULL) + { + *size = 4096; + *line = HeapAlloc(GetProcessHeap(), 0, *size); + } + while (*line != NULL) + { + if (fgets(&(*line)[pos], *size - pos, file) == NULL) + { + HeapFree(GetProcessHeap(), 0, *line); + *line = NULL; + if (feof(file)) + return TRUE; + return FALSE; + } + pos = strlen(*line); + cr = strchr(*line, '\n'); + if (cr == NULL) + { + char *line2; + (*size) *= 2; + line2 = HeapReAlloc(GetProcessHeap(), 0, *line, *size); + if (line2) + *line = line2; + else + { + HeapFree(GetProcessHeap(), 0, *line); + *line = NULL; + } + } + else + { + *cr = 0; + return TRUE; + } + } + return FALSE; +} + +static BOOL add_mimes(const char *xdg_data_dir, struct list *mime_types) +{ + char *globs_filename = NULL; + BOOL ret = TRUE; + globs_filename = heap_printf("%s/mime/globs", xdg_data_dir); + if (globs_filename) + { + FILE *globs_file = fopen(globs_filename, "r"); + if (globs_file) /* doesn't have to exist */ + { + char *line = NULL; + int size = 0; + while (ret && (ret = next_line(globs_file, &line, &size)) && line) + { + char *pos; + struct xdg_mime_type *mime_type_entry = NULL; + if (line[0] != '#' && (pos = strchr(line, ':'))) + { + mime_type_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xdg_mime_type)); + if (mime_type_entry) + { + *pos = 0; + mime_type_entry->mimeType = line; + mime_type_entry->glob = pos + 1; + list_add_tail(mime_types, &mime_type_entry->entry); + } + else + ret = FALSE; + } + } + HeapFree(GetProcessHeap(), 0, line); + fclose(globs_file); + } + HeapFree(GetProcessHeap(), 0, globs_filename); + } + else + ret = FALSE; + return ret; +} + +static void free_native_mime_types(struct list *native_mime_types) +{ + struct xdg_mime_type *mime_type_entry, *mime_type_entry2; + + LIST_FOR_EACH_ENTRY_SAFE(mime_type_entry, mime_type_entry2, native_mime_types, struct xdg_mime_type, entry) + { + list_remove(&mime_type_entry->entry); + HeapFree(GetProcessHeap(), 0, mime_type_entry->mimeType); + HeapFree(GetProcessHeap(), 0, mime_type_entry); + } + HeapFree(GetProcessHeap(), 0, native_mime_types); +} + +static BOOL build_native_mime_types(const char *xdg_data_home, struct list **mime_types) +{ + char *xdg_data_dirs; + BOOL ret; + + *mime_types = NULL; + + xdg_data_dirs = getenv("XDG_DATA_DIRS"); + if (xdg_data_dirs == NULL) + xdg_data_dirs = heap_printf("/usr/local/share/:/usr/share/"); + else + xdg_data_dirs = heap_printf("%s", xdg_data_dirs); + + if (xdg_data_dirs) + { + *mime_types = HeapAlloc(GetProcessHeap(), 0, sizeof(struct list)); + if (*mime_types) + { + const char *begin; + char *end; + + list_init(*mime_types); + ret = add_mimes(xdg_data_home, *mime_types); + if (ret) + { + for (begin = xdg_data_dirs; (end = strchr(begin, ':')); begin = end + 1) + { + *end = '\0'; + ret = add_mimes(begin, *mime_types); + *end = ':'; + if (!ret) + break; + } + if (ret) + ret = add_mimes(begin, *mime_types); + } + } + else + ret = FALSE; + HeapFree(GetProcessHeap(), 0, xdg_data_dirs); + } + else + ret = FALSE; + if (!ret && *mime_types) + { + free_native_mime_types(*mime_types); + *mime_types = NULL; + } + return ret; +} + +static BOOL generate_associations(const char *xdg_data_home, const char *packages_dir, const char *applications_dir) +{ + struct list *nativeMimeTypes = NULL; + + if (!build_native_mime_types(xdg_data_home, &nativeMimeTypes)) + { + WINE_ERR("could not build native MIME types\n"); + return FALSE; + } + return TRUE; +} + static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) { static const WCHAR startW[] = {'\\','c','o','m','m','a','n','d', @@ -1708,6 +1875,8 @@ static void RefreshFileTypeAssociations(void) } create_directories(applications_dir); + generate_associations(xdg_data_dir, packages_dir, applications_dir); + end: if (hSem) { -- 2.11.4.GIT