From 6c668868e95fafb730552fd7567a0a6e3786c368 Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 19 Jul 2015 21:04:24 +0800 Subject: death of mimedb: remove mimedb from the tree --- .gitignore | 1 - Doxyfile | 14 +- Makefile.in | 28 +- debian/copyright | 48 -- doc_src/faq.hdr | 2 +- doc_src/license.hdr | 4 +- doc_src/mimedb.txt | 28 - fish.xcodeproj/project.pbxproj | 26 - mimedb.cpp | 1471 ---------------------------------------- share/completions/mimedb.fish | 9 - share/functions/mimedb.fish | 12 - xdgmime.cpp | 722 -------------------- xdgmime.h | 93 --- xdgmimealias.cpp | 185 ----- xdgmimealias.h | 50 -- xdgmimeglob.cpp | 473 ------------- xdgmimeglob.h | 65 -- xdgmimeint.cpp | 155 ----- xdgmimeint.h | 73 -- xdgmimemagic.cpp | 790 --------------------- xdgmimemagic.h | 54 -- xdgmimeparent.cpp | 220 ------ xdgmimeparent.h | 50 -- 23 files changed, 4 insertions(+), 4569 deletions(-) delete mode 100644 doc_src/mimedb.txt delete mode 100644 mimedb.cpp delete mode 100644 share/completions/mimedb.fish delete mode 100644 share/functions/mimedb.fish delete mode 100644 xdgmime.cpp delete mode 100644 xdgmime.h delete mode 100644 xdgmimealias.cpp delete mode 100644 xdgmimealias.h delete mode 100644 xdgmimeglob.cpp delete mode 100644 xdgmimeglob.h delete mode 100644 xdgmimeint.cpp delete mode 100644 xdgmimeint.h delete mode 100644 xdgmimemagic.cpp delete mode 100644 xdgmimemagic.h delete mode 100644 xdgmimeparent.cpp delete mode 100644 xdgmimeparent.h diff --git a/.gitignore b/.gitignore index b822519f..13d5ce32 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ fish fish_indent fish_tests fish.pc -mimedb seq set_color share/config.fish diff --git a/Doxyfile b/Doxyfile index 47425dd6..d12875a5 100644 --- a/Doxyfile +++ b/Doxyfile @@ -835,19 +835,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = print_help.c \ - xdgmimealias.c \ - xdgmimealias.h \ - xdgmime.c \ - xdgmimeglob.c \ - xdgmimeglob.h \ - xdgmime.h \ - xdgmimeint.c \ - xdgmimeint.h \ - xdgmimemagic.c \ - xdgmimemagic.h \ - xdgmimeparent.c \ - xdgmimeparent.h +EXCLUDE = print_help.c # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/Makefile.in b/Makefile.in index c896d33d..5329c68d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -111,15 +111,6 @@ BUILTIN_FILES := builtin_set.cpp builtin_commandline.cpp \ FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o -# -# All objects needed to build mimedb -# - -MIME_OBJS := mimedb.o print_help.o xdgmimealias.o xdgmime.o \ - xdgmimeglob.o xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o \ - common.o fish_version.o - - # # Files containing user documentation # @@ -178,7 +169,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish) # Programs to install # -PROGRAMS := fish mimedb fish_indent +PROGRAMS := fish fish_indent # # Manual pages to install @@ -776,14 +767,6 @@ fish_tests: $(FISH_TESTS_OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS_FISH) $(FISH_TESTS_OBJS) $(LIBS) -o $@ -# -# Build the mimedb program. -# - -mimedb: $(MIME_OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(MIME_OBJS) $(LIBS) -o $@ - - # # Build the fish_indent program. # @@ -954,8 +937,6 @@ key_reader.o: config.h common.h util.h fallback.h signal.h input_common.h kill.o: config.h signal.h fallback.h util.h wutil.h common.h kill.h proc.h kill.o: io.h parse_tree.h tokenizer.h parse_constants.h sanity.h env.h exec.h kill.o: path.h -mimedb.o: config.h xdgmime.h fallback.h signal.h util.h print_help.h -mimedb.o: fish_version.h output.o: config.h signal.h fallback.h util.h wutil.h common.h expand.h output.o: parse_constants.h output.h screen.h highlight.h env.h color.h pager.o: config.h pager.h complete.h util.h common.h screen.h highlight.h @@ -1015,10 +996,3 @@ wildcard.o: config.h fallback.h signal.h util.h wutil.h common.h complete.h wildcard.o: wildcard.h expand.h parse_constants.h reader.h io.h highlight.h wildcard.o: env.h color.h exec.h proc.h parse_tree.h tokenizer.h wutil.o: config.h fallback.h signal.h util.h common.h wutil.h -xdgmime.o: xdgmime.h xdgmimeint.h xdgmimeglob.h xdgmimemagic.h xdgmimealias.h -xdgmime.o: xdgmimeparent.h -xdgmimealias.o: xdgmimealias.h xdgmime.h xdgmimeint.h -xdgmimeglob.o: xdgmimeglob.h xdgmime.h xdgmimeint.h -xdgmimeint.o: xdgmimeint.h xdgmime.h -xdgmimemagic.o: xdgmimemagic.h xdgmime.h xdgmimeint.h -xdgmimeparent.o: xdgmimeparent.h xdgmime.h xdgmimeint.h diff --git a/debian/copyright b/debian/copyright index db2a6dcf..675ae095 100644 --- a/debian/copyright +++ b/debian/copyright @@ -69,54 +69,6 @@ license. suitability of this software for any purpose. It is provided "as is" without express or implied warranty. -The xdgmime library, written and copyrighted by Red Hat, Inc, is used -by the mimedb command, which is a part of fish. It is released under -the LGPL license. - -The copyright for the xdgmime-related files belong to the following people -xdgmime.c - Copyright (C) 2003,2004 Red Hat, Inc. - Copyright (C) 2003,2004 Jonathan Blandford - -xdgmime.h - Copyright (C) 2003 Red Hat, Inc. - Copyright (C) 2003 Jonathan Blandford - -xdgmimealias.c, xdgmimealias.h - Copyright (C) 2004 Red Hat, Inc. - Copyright (C) 2004 Matthias Clasen - -xdgmimeglob.c, xdgmimeglob.h - Copyright (C) 2003 Red Hat, Inc. - Copyright (C) 2003 Jonathan Blandford - -xdgmimeint.c, xdgmimeint.h - Copyright (C) 2003 Red Hat, Inc. - Copyright (C) 2003 Jonathan Blandford - -xdgmimemagic.c, xdgmimemagic.h - Copyright (C) 2003 Red Hat, Inc. - Copyright (C) 2003 Jonathan Blandford - -xdgmimeparent.c, xdgmimeparent.h - Copyright (C) 2004 Red Hat, Inc. - Copyright (C) 2004 Matthias Clasen - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301, USA. - Fish contains code from the glibc library, namely the wcstok function in fallback.c. This code is licensed under the LGPL. diff --git a/doc_src/faq.hdr b/doc_src/faq.hdr index 75e4bb74..03d1983f 100644 --- a/doc_src/faq.hdr +++ b/doc_src/faq.hdr @@ -212,7 +212,7 @@ Next, do the following (assuming fish was installed to /usr/local): rm -Rf /usr/local/etc/fish /usr/local/share/fish ~/.config/fish rm /usr/local/share/man/man1/fish*.1 cd /usr/local/bin -rm -f fish mimedb fish_indent +rm -f fish fish_indent \endfish \htmlonly[block] diff --git a/doc_src/license.hdr b/doc_src/license.hdr index fff8084e..b9d5fc8c 100644 --- a/doc_src/license.hdr +++ b/doc_src/license.hdr @@ -129,9 +129,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE ---- -## License for xdgmime and glibc - -The xdgmime library, written and copyrighted by Red Hat, Inc, is used by the mimedb command, which is a part of fish. It is released under the LGPL, version 2 or later, or under the Academic Free License, version 2. Version 2 of the LGPL license agreement is included below. +## License for glibc Fish contains code from the glibc library, namely the wcstok function. This code is licensed under the LGPL, version 2 or later. Version 2 of the LPGL license agreement is included below. diff --git a/doc_src/mimedb.txt b/doc_src/mimedb.txt deleted file mode 100644 index 19747444..00000000 --- a/doc_src/mimedb.txt +++ /dev/null @@ -1,28 +0,0 @@ -\section mimedb mimedb - lookup file information via the mime database - -\subsection mimedb-synopsis Synopsis -\fish{synopsis} -mimedb [OPTIONS] FILES... -\endfish - -\subsection mimedb-description Description - -`mimedb` queries the MIME type database and the `.desktop` files installed on the system in order to find information on the files listed in `FILES`. The information that `mimedb` can retrieve includes the MIME type for a file, a description of the type, and the default action that can be performed on the file. `mimedb` can also be used to launch the default action for this file. - -The following options are available: - -- `-t`, `--input-file-data` determines the files' type both by their filename and by their contents (default behaviour). - -- `-f`, `--input-filename` determines the files' type by their filename. - -- `-i`, `--input-mime` specifies that the arguments are not files, but MIME types. - -- `-m`, `--output-mime` outputs the MIME type of each file (default behaviour). - -- `-f`, `--output-description` outputs the description of each MIME type. - -- `-a`, `--output-action` outputs the default action of each MIME type. - -- `-l`, `--launch` launches the default action for the specified files. - -- `-v`, `--version` displays the version number and exits. diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 7b0982d5..9fac7d80 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -413,12 +413,6 @@ D0A0852713B3ACEE0099B651 /* wgetopt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wgetopt.h; sourceTree = ""; }; D0A0852813B3ACEE0099B651 /* wildcard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wildcard.h; sourceTree = ""; }; D0A0852913B3ACEE0099B651 /* wutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wutil.h; sourceTree = ""; }; - D0A0852A13B3ACEE0099B651 /* xdgmime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmime.h; sourceTree = ""; }; - D0A0852B13B3ACEE0099B651 /* xdgmimealias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimealias.h; sourceTree = ""; }; - D0A0852C13B3ACEE0099B651 /* xdgmimeglob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeglob.h; sourceTree = ""; }; - D0A0852D13B3ACEE0099B651 /* xdgmimeint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeint.h; sourceTree = ""; }; - D0A0852E13B3ACEE0099B651 /* xdgmimemagic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimemagic.h; sourceTree = ""; }; - D0A0852F13B3ACEE0099B651 /* xdgmimeparent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdgmimeparent.h; sourceTree = ""; }; D0A0853013B3ACEE0099B651 /* builtin_commandline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_commandline.cpp; sourceTree = ""; }; D0A0853113B3ACEE0099B651 /* builtin_complete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_complete.cpp; sourceTree = ""; }; D0A0853213B3ACEE0099B651 /* builtin_jobs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin_jobs.cpp; sourceTree = ""; }; @@ -446,7 +440,6 @@ D0A0854D13B3ACEE0099B651 /* iothread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iothread.cpp; sourceTree = ""; }; D0A0854E13B3ACEE0099B651 /* key_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = key_reader.cpp; sourceTree = ""; }; D0A0854F13B3ACEE0099B651 /* kill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kill.cpp; sourceTree = ""; }; - D0A0855013B3ACEE0099B651 /* mimedb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mimedb.cpp; sourceTree = ""; }; D0A0855113B3ACEE0099B651 /* output.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = output.cpp; sourceTree = ""; }; D0A0855213B3ACEE0099B651 /* parse_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_util.cpp; sourceTree = ""; }; D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_keywords.cpp; sourceTree = ""; }; @@ -463,12 +456,6 @@ D0A0855F13B3ACEE0099B651 /* wgetopt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wgetopt.cpp; sourceTree = ""; }; D0A0856013B3ACEE0099B651 /* wildcard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wildcard.cpp; sourceTree = ""; }; D0A0856113B3ACEE0099B651 /* wutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wutil.cpp; sourceTree = ""; }; - D0A0856213B3ACEE0099B651 /* xdgmime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmime.cpp; sourceTree = ""; }; - D0A0856313B3ACEE0099B651 /* xdgmimealias.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimealias.cpp; sourceTree = ""; }; - D0A0856413B3ACEE0099B651 /* xdgmimeglob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeglob.cpp; sourceTree = ""; }; - D0A0856513B3ACEE0099B651 /* xdgmimeint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeint.cpp; sourceTree = ""; }; - D0A0856613B3ACEE0099B651 /* xdgmimemagic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimemagic.cpp; sourceTree = ""; }; - D0A0856713B3ACEE0099B651 /* xdgmimeparent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xdgmimeparent.cpp; sourceTree = ""; }; D0A564D2168CF34A00AF6161 /* doc_src */ = {isa = PBXFileReference; lastKnownFileType = folder; path = doc_src; sourceTree = ""; }; D0A564F1168D0BAB00AF6161 /* man */ = {isa = PBXFileReference; lastKnownFileType = text; path = man; sourceTree = BUILT_PRODUCTS_DIR; }; D0A564F2168D1F2000AF6161 /* build_documentation.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = build_documentation.sh; path = build_tools/build_documentation.sh; sourceTree = ""; }; @@ -646,7 +633,6 @@ D0A0854F13B3ACEE0099B651 /* kill.cpp */, D0A0854E13B3ACEE0099B651 /* key_reader.cpp */, D03EE83814DF88B200FC7150 /* lru.h */, - D0A0855013B3ACEE0099B651 /* mimedb.cpp */, D0A0851A13B3ACEE0099B651 /* output.h */, D0A0855113B3ACEE0099B651 /* output.cpp */, D032388A1849D1980032CF2C /* pager.h */, @@ -687,18 +673,6 @@ D0A0856013B3ACEE0099B651 /* wildcard.cpp */, D0A0852913B3ACEE0099B651 /* wutil.h */, D0A0856113B3ACEE0099B651 /* wutil.cpp */, - D0A0852A13B3ACEE0099B651 /* xdgmime.h */, - D0A0856213B3ACEE0099B651 /* xdgmime.cpp */, - D0A0852B13B3ACEE0099B651 /* xdgmimealias.h */, - D0A0856313B3ACEE0099B651 /* xdgmimealias.cpp */, - D0A0852C13B3ACEE0099B651 /* xdgmimeglob.h */, - D0A0856413B3ACEE0099B651 /* xdgmimeglob.cpp */, - D0A0852D13B3ACEE0099B651 /* xdgmimeint.h */, - D0A0856513B3ACEE0099B651 /* xdgmimeint.cpp */, - D0A0852E13B3ACEE0099B651 /* xdgmimemagic.h */, - D0A0856613B3ACEE0099B651 /* xdgmimemagic.cpp */, - D0A0852F13B3ACEE0099B651 /* xdgmimeparent.h */, - D0A0856713B3ACEE0099B651 /* xdgmimeparent.cpp */, ); name = Sources; sourceTree = ""; diff --git a/mimedb.cpp b/mimedb.cpp deleted file mode 100644 index bbc29227..00000000 --- a/mimedb.cpp +++ /dev/null @@ -1,1471 +0,0 @@ -/** \file mimedb.c - -mimedb is a program for checking the mimetype, description and -default action associated with a file or mimetype. It uses the -xdgmime library written by the fine folks at freedesktop.org. There does -not seem to be any standard way for the user to change the preferred -application yet. - -The first implementation of mimedb used xml_grep to parse the xml -file for the mime entry to determine the description. This was abandoned -because of the performance implications of parsing xml. The current -version only does a simple string search, which is much, much -faster but it might fall on it's head. - -This code is Copyright 2005-2008 Axel Liljencrantz. -It is released under the GPL. - -The xdgmime library is dual licensed under LGPL/artistic -license. Read the source code of the library for more information. -*/ - -#include "config.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#ifdef HAVE_GETOPT_H -#include -#endif - -#if HAVE_LIBINTL_H -#include -#endif - -#include "xdgmime.h" -#include "fallback.h" -#include "util.h" -#include "print_help.h" -#include "fish_version.h" - -typedef std::vector string_list_t; - -/** - Location of the applications .desktop file, relative to a base mime directory -*/ -#define APPLICATIONS_DIR "applications/" - -/** - Location of the mime xml database, relative to a base mime directory -*/ -#define MIME_DIR "mime/" -/** - Filename suffix for XML files -*/ -#define MIME_SUFFIX ".xml" - -/** - Start tag for langauge-specific comment -*/ -#define START_TAG "" - -/** - End tab for comment -*/ -#define STOP_TAG "" - -/** - File contains cached list of mime actions -*/ -#define DESKTOP_DEFAULT "applications/defaults.list" - -/** - Size for temporary string buffer used to make a regex for language - specific descriptions -*/ -#define BUFF_SIZE 1024 - -/** - Program name -*/ -#define MIMEDB "mimedb" - -/** - Getopt short switches for mimedb -*/ -#define GETOPT_STRING "tfimdalhv" - -/** - Error message if system call goes wrong. -*/ -#define ERROR_SYSTEM "%s: Could not execute command \"%s\"\n" - -/** - Exit code if system call goes wrong. -*/ -#define STATUS_ERROR_SYSTEM 1 - - -/** - All types of input and output possible -*/ -enum -{ - FILEDATA, - FILENAME, - MIMETYPE, - DESCRIPTION, - ACTION, - LAUNCH -} -; - -/** - Regular expression variable used to find start tag of description -*/ -static regex_t *start_re=0; -/** - Regular expression variable used to find end tag of description -*/ -static regex_t *stop_re=0; - -/** - Error flag. Non-zero if something bad happened. -*/ -static int error = 0; - -/** - String of characters to send to system() to launch a file -*/ -static char *launch_buff=0; - -/** - Length of the launch_buff buffer -*/ -static int launch_len=0; -/** - Current position in the launch_buff buffer -*/ -static int launch_pos=0; - -/** - gettext alias -*/ -#ifdef USE_GETTEXT -#define _(string) fish_gettext(string) -#else -#define _(string) (string) -#endif - -/** - Call malloc, set error flag and print message on failure -*/ -void *my_malloc(size_t s) -{ - void *res = malloc(s); - if (!s) - { - error=1; - fprintf(stderr, _("%s: Out of memory\n"), MIMEDB); - } - return res; -} - -/** - Duplicate string, set error flag and print message on failure -*/ -char *my_strdup(const char *s) -{ - char *res = strdup(s); - if (!s) - { - error=1; - fprintf(stderr, _("%s: Out of memory\n"), MIMEDB); - } - return res; -} - - -/** - Search the file \c filename for the first line starting with \c - match, which is returned in a newly allocated string. -*/ -static const char * search_ini(const char *filename, const char *match) -{ - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - FILE *f = fopen(filename, "r"); - char buf[4096]; - int len=strlen(match); - int done = 0; - - if (!f) - { - perror("fopen"); - error=1; - return 0; - } - while (!done) - { - if (!fgets(buf, 4096, f)) - { - if (!feof(f)) - { - perror("fgets"); - error=1; - } - buf[0]=0; - done = 1; - } - else if (strncmp(buf, match, len) == 0 && buf[len] == '=') - { - done=1; - } - } - fclose(f); - if (buf[0]) - { - char *res=strdup(buf); - if (res) - { - if (res[strlen(res)-1]=='\n') - res[strlen(res)-1]='\0'; - } - return res; - } - else - return (char *)0; -} - -/** - Test if the specified file exists. If it does not, also try - replacing dashes with slashes in \c in. -*/ -static char *file_exists(const char *dir, const char *in) -{ - int dir_len = strlen(dir); - int need_sep = dir[dir_len - 1] != '/'; - char *filename = (char *)my_malloc(dir_len + need_sep + strlen(in) + 1); - char *replaceme; - struct stat buf; - -// fprintf( stderr, "Check %s%s\n", dir, in ); - - if (!filename) - { - return 0; - } - strcpy(filename, dir); - if (need_sep) - filename[dir_len++] = '/'; - strcpy(filename + dir_len, in); - - if (!stat(filename, &buf)) - return filename; - - free(filename); - - /* - DOH! File does not exist. But all is not lost. KDE sometimes uses - a slash in the name as a directory separator. We try to replace - a dash with a slash and try again. - */ - replaceme = const_cast(strchr(in, '-')); - if (replaceme) - { - char *res; - - *replaceme = '/'; - res = file_exists(dir, in); - *replaceme = '-'; - return res; - } - /* - OK, no more slashes left. We really are screwed. Nothing to to - but admit defeat and go home. - */ - return 0; -} - - -/** - Try to find the specified file in any of the possible directories - where mime files can be located. This code is shamelessly stolen - from xdg_run_command_on_dirs. - - \param list Full file paths will be appended to this list. - \param f The relative filename search for the data directories. - \param all If zero, then stop after the first filename. - \return The number of filenames added to the list. -*/ -static int append_filenames(string_list_t &list, const char *f, int all) -{ - size_t prev_count = list.size(); - char *result; - const char *xdg_data_home; - const char *xdg_data_dirs; - const char *ptr; - - xdg_data_home = getenv("XDG_DATA_HOME"); - if (xdg_data_home) - { - result = file_exists(xdg_data_home, f); - if (result) - { - list.push_back(result); - if (!all) - return 1; - } - } - else - { - const char *home; - - home = getenv("HOME"); - if (home != NULL) - { - char *guessed_xdg_home; - - guessed_xdg_home = (char *)my_malloc(strlen(home) + strlen("/.local/share") + 1); - if (!guessed_xdg_home) - return 0; - - strcpy(guessed_xdg_home, home); - strcat(guessed_xdg_home, "/.local/share"); - result = file_exists(guessed_xdg_home, f); - free(guessed_xdg_home); - - if (result) - { - list.push_back(result); - if (!all) - return 1; - } - } - } - - xdg_data_dirs = getenv("XDG_DATA_DIRS"); - if (xdg_data_dirs == NULL) - xdg_data_dirs = "/usr/local/share:/usr/share"; - - ptr = xdg_data_dirs; - - while (*ptr != '\000') - { - const char *end_ptr; - char *dir; - int len; - - end_ptr = ptr; - while (*end_ptr != ':' && *end_ptr != '\000') - end_ptr ++; - - if (end_ptr == ptr) - { - ptr++; - continue; - } - - len = end_ptr - ptr; - dir = (char *)my_malloc(len + 1); - if (!dir) - return 0; - - strncpy(dir, ptr, len); - dir[len] = '\0'; - result = file_exists(dir, f); - - free(dir); - - if (result) - { - list.push_back(result); - if (!all) - { - return 1; - } - } - - ptr = end_ptr; - } - return list.size() - prev_count; -} - -/** - Find at most one file relative to the XDG data directories; returns the empty string on failure -*/ -static std::string get_filename(char *f) -{ - string_list_t list; - - append_filenames(list, f, 0); - if (list.empty()) - { - return ""; - } - else - { - return list.back(); - } -} - -/** - Remove excessive whitespace from string. Replaces arbitrary sequence - of whitespace with a single space. Also removes any leading and - trailing whitespace -*/ -static char *munge(char *in) -{ - char *out = (char *)my_malloc(strlen(in)+1); - char *p=out; - int had_whitespace = 0; - int printed = 0; - if (!out) - { - return 0; - } - - while (1) - { -// fprintf( stderr, "%c\n", *in ); - - switch (*in) - { - case ' ': - case '\n': - case '\t': - case '\r': - { - had_whitespace = 1; - break; - } - case '\0': - *p = '\0'; - return out; - default: - { - if (printed && had_whitespace) - { - *(p++)=' '; - } - printed=1; - had_whitespace=0; - *(p++)=*in; - break; - } - } - in++; - } - fprintf(stderr, _("%s: Unknown error in munge()\n"), MIMEDB); - error=1; - return 0; -} - -/** - Return a regular expression that matches all strings specifying the current locale -*/ -static char *get_lang_re() -{ - - static char buff[BUFF_SIZE]; - const char *lang = setlocale(LC_MESSAGES, 0); - int close=0; - char *out=buff; - - if ((1+strlen(lang)*4) >= BUFF_SIZE) - { - fprintf(stderr, _("%s: Locale string too long\n"), MIMEDB); - error = 1; - return 0; - } - - for (; *lang; lang++) - { - switch (*lang) - { - case '@': - case '.': - case '_': - if (close) - { - *out++ = ')'; - *out++ = '?'; - } - - close=1; - *out++ = '('; - *out++ = *lang; - break; - - default: - *out++ = *lang; - } - } - - if (close) - { - *out++ = ')'; - *out++ = '?'; - } - *out++=0; - - return buff; -} - -/** - Get description for a specified mimetype. -*/ -static char *get_description(const char *mimetype) -{ - char *fn_part; - - std::string fn; - int fd; - struct stat st; - char *contents; - char *start=0, *stop=0, *best_start=0; - - if (!start_re) - { - char *lang; - char buff[BUFF_SIZE]; - - lang = get_lang_re(); - if (!lang) - return 0; - - snprintf(buff, BUFF_SIZE, START_TAG, lang, lang); - - start_re = (regex_t *)my_malloc(sizeof(regex_t)); - stop_re = (regex_t *)my_malloc(sizeof(regex_t)); - - int reg_status; - if ((reg_status = regcomp(start_re, buff, REG_EXTENDED))) - { - char regerrbuf[BUFF_SIZE]; - regerror(reg_status, start_re, regerrbuf, BUFF_SIZE); - fprintf(stderr, _("%s: Could not compile regular expressions %s with error %s\n"), MIMEDB, buff, regerrbuf); - error=1; - - } - else if ((reg_status = regcomp(stop_re, STOP_TAG, REG_EXTENDED))) - { - char regerrbuf[BUFF_SIZE]; - regerror(reg_status, stop_re, regerrbuf, BUFF_SIZE); - fprintf(stderr, _("%s: Could not compile regular expressions %s with error %s\n"), MIMEDB, buff, regerrbuf); - error=1; - - } - - if (error) - { - free(start_re); - free(stop_re); - start_re = stop_re = 0; - - return 0; - } - } - - fn_part = (char *)my_malloc(strlen(MIME_DIR) + strlen(mimetype) + strlen(MIME_SUFFIX) + 1); - - if (!fn_part) - { - return 0; - } - - strcpy(fn_part, MIME_DIR); - strcat(fn_part, mimetype); - strcat(fn_part, MIME_SUFFIX); - - fn = get_filename(fn_part); //malloc( strlen(MIME_DIR) +strlen( MIME_SUFFIX)+ strlen( mimetype ) + 1 ); - free(fn_part); - - if (fn.empty()) - { - return 0; - } - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - fd = open(fn.c_str(), O_RDONLY); - -// fprintf( stderr, "%s\n", fn ); - - if (fd == -1) - { - perror("open"); - error=1; - return 0; - } - - if (stat(fn.c_str(), &st)) - { - perror("stat"); - error=1; - return 0; - } - - contents = (char *)my_malloc(st.st_size + 1); - if (!contents) - { - return 0; - } - - if (read(fd, contents, st.st_size) != st.st_size) - { - perror("read"); - error=1; - free((void *)contents); - close(fd); - return 0; - } - - /* - Don't need to check exit status of close on read-only file descriptors - */ - close(fd); - - contents[st.st_size]=0; - regmatch_t match[1]; - int w = -1; - - start=contents; - - /* - On multiple matches, use the longest match, should be a pretty - good heuristic for best match... - */ - while (!regexec(start_re, start, 1, match, 0)) - { - int new_w = match[0].rm_eo - match[0].rm_so; - start += match[0].rm_eo; - - if (new_w > w) - { - /* - New match is for a longer match then the previous - match, so we use the new match - */ - w=new_w; - best_start = start; - } - } - - if (w != -1) - { - start = best_start; - if (!regexec(stop_re, start, 1, match, 0)) - { - /* - We've found the beginning and the end of a suitable description - */ - char *res; - - stop = start + match[0].rm_so; - *stop = '\0'; - res = munge(start); - free(contents); - return res; - } - } - free(contents); - fprintf(stderr, _("%s: No description for type %s\n"), MIMEDB, mimetype); - error=1; - return 0; - -} - - -/** - Get default action for a specified mimetype. -*/ -static char *get_action(const char *mimetype) -{ - char *res=0; - - const char *launcher, *end; - string_list_t mime_filenames; - - const char *launcher_str = NULL; - const char *launcher_command_str, *launcher_command; - char *launcher_full; - - if (!append_filenames(mime_filenames, DESKTOP_DEFAULT, 1)) - { - return 0; - } - - for (size_t i = 0; i < mime_filenames.size(); i++) - { - launcher_str = search_ini(mime_filenames.at(i).c_str(), mimetype); - if (launcher_str) - break; - } - - - if (!launcher_str) - { - /* - This type does not have a launcher. Try the supertype! - */ -// fprintf( stderr, "mimedb: %s does not have launcher, try supertype\n", mimetype ); - const char ** parents = xdg_mime_get_mime_parents(mimetype); - - const char **p; - if (parents) - { - for (p=parents; *p; p++) - { - char *a = get_action(*p); - if (a != 0) - return a; - } - } - /* - Just in case subclassing doesn't work, (It doesn't on Fedora - Core 3) we also test some common subclassings. - */ - - if (strncmp(mimetype, "text/plain", 10) != 0 && strncmp(mimetype, "text/", 5) == 0) - return get_action("text/plain"); - - return 0; - } - -// fprintf( stderr, "WOOT %s\n", launcher_str ); - launcher = const_cast(strchr(launcher_str, '=')); - - if (!launcher) - { - fprintf(stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str); - error=1; - return 0; - } - - /* Skip the = */ - launcher++; - - /* Make one we can change */ - std::string mut_launcher = launcher; - - /* Only use first launcher */ - end = strchr(launcher, ';'); - if (end) - mut_launcher.resize(end - launcher); - - launcher_full = (char *)my_malloc(mut_launcher.size() + strlen(APPLICATIONS_DIR)+1); - if (!launcher_full) - { - free((void *)launcher_str); - return 0; - } - - strcpy(launcher_full, APPLICATIONS_DIR); - strcat(launcher_full, mut_launcher.c_str()); - free((void *)launcher_str); - - std::string launcher_filename = get_filename(launcher_full); - - free(launcher_full); - - launcher_command_str = search_ini(launcher_filename.c_str(), "Exec"); - - if (!launcher_command_str) - { - fprintf(stderr, - _("%s: Default launcher '%s' does not specify how to start\n"), MIMEDB, - launcher_filename.c_str()); - return 0; - } - - launcher_command = strchr(launcher_command_str, '='); - launcher_command++; - - res = my_strdup(launcher_command); - - free((void *)launcher_command_str); - - return res; -} - - -/** - Helper function for launch. Write the specified byte to the string we will execute -*/ -static void writer(char c) -{ - if (launch_len == -1) - return; - - if (launch_len <= launch_pos) - { - int new_len = launch_len?2*launch_len:256; - char *new_buff = (char *)realloc(launch_buff, new_len); - if (!new_buff) - { - free(launch_buff); - launch_len = -1; - error=1; - return; - } - launch_buff = new_buff; - launch_len = new_len; - - } - launch_buff[launch_pos++]=c; -} - -/** - Write out the specified byte in hex -*/ -static void writer_hex(int num) -{ - int a, b; - a = num /16; - b = num %16; - - writer(a>9?('A'+a-10):('0'+a)); - writer(b>9?('A'+b-10):('0'+b)); -} - -/** - Return current directory in newly allocated string -*/ -static char *my_getcwd() -{ - size_t size = 100; - while (1) - { - char *buffer = (char *) malloc(size); - if (getcwd(buffer, size) == buffer) - return buffer; - free(buffer); - if (errno != ERANGE) - return 0; - size *= 2; - } -} - -/** - Return absolute filename of specified file - */ -static const char *get_fullfile(const char *file) -{ - const char *fullfile; - - if (file[0] == '/') - { - fullfile = file; - } - else - { - char *cwd = my_getcwd(); - if (!cwd) - { - error = 1; - perror("getcwd"); - return 0; - } - - int l = strlen(cwd); - - char *tmp = (char *)my_malloc(l + strlen(file)+2); - if (!tmp) - { - free(cwd); - return 0; - } - strcpy(tmp, cwd); - if (cwd[l-1] != '/') - strcat(tmp, "/"); - strcat(tmp, file); - - free(cwd); - fullfile = tmp; - } - return fullfile; -} - - -/** - Write specified file as an URL -*/ -static void write_url(const char *file) -{ - const char *fullfile = get_fullfile(file); - const char *str = fullfile; - - if (str == 0) - { - launch_len = -1; - return; - } - - writer('f'); - writer('i'); - writer('l'); - writer('e'); - writer(':'); - writer('/'); - writer('/'); - while (*str) - { - if (((*str >= 'a') && (*str <='z')) || - ((*str >= 'A') && (*str <='Z')) || - ((*str >= '0') && (*str <='9')) || - (strchr("-_.~/",*str) != 0)) - { - writer(*str); - } - else if (strchr("()?&=",*str) != 0) - { - writer('\\'); - writer(*str); - } - else - { - writer('%'); - writer_hex((unsigned char)*str); - } - str++; - } - if (fullfile != file) - free((void *)fullfile); - -} - -/** - Write specified file -*/ -static void write_file(const char *file, int print_path) -{ - const char *fullfile; - const char *str; - if (print_path) - { - fullfile = get_fullfile(file); - str = fullfile; - } - else - { - char *tmp = my_strdup(file); - if (!tmp) - { - return; - } - str = basename(tmp); - fullfile = tmp; - } - - if (!str) - { - error = 1; - return; - } - - while (*str) - { - switch (*str) - { - case ')': - case '(': - case '-': - case '#': - case '$': - case '}': - case '{': - case ']': - case '[': - case '*': - case '?': - case ' ': - case '|': - case '<': - case '>': - case '^': - case '&': - case '\\': - case '`': - case '\'': - case '\"': - writer('\\'); - writer(*str); - break; - - case '\n': - writer('\\'); - writer('n'); - break; - - case '\r': - writer('\\'); - writer('r'); - break; - - case '\t': - writer('\\'); - writer('t'); - break; - - case '\b': - writer('\\'); - writer('b'); - break; - - case '\v': - writer('\\'); - writer('v'); - break; - - default: - writer(*str); - break; - } - str++; - } - - if (fullfile != file) - free((void *)fullfile); -} - -/** - Use the specified launch filter to launch all the files in the specified list. - - \param filter the action to take - \param files the list of files for which to perform the action - \param fileno an internal value. Should always be set to zero. -*/ -static void launch(char *filter, const string_list_t &files, size_t fileno) -{ - char *filter_org=filter; - int count=0; - int launch_again=0; - - if (files.size() <= fileno) - return; - - - launch_pos=0; - - for (; *filter && !error; filter++) - { - if (*filter == '%') - { - filter++; - switch (*filter) - { - case 'u': - { - launch_again = 1; - write_url(files.at(fileno).c_str()); - break; - } - case 'U': - { - for (size_t i=0; i launch_hash_t; - launch_hash_t launch_hash; - - locale_init(); - - /* - Parse options - */ - while (1) - { - static struct option - long_options[] = - { - { - "input-file-data", no_argument, 0, 't' - } - , - { - "input-filename", no_argument, 0, 'f' - } - , - { - "input-mime", no_argument, 0, 'i' - } - , - { - "output-mime", no_argument, 0, 'm' - } - , - { - "output-description", no_argument, 0, 'd' - } - , - { - "output-action", no_argument, 0, 'a' - } - , - { - "help", no_argument, 0, 'h' - } - , - { - "version", no_argument, 0, 'v' - } - , - { - "launch", no_argument, 0, 'l' - } - , - { - 0, 0, 0, 0 - } - } - ; - - int opt_index = 0; - - int opt = getopt_long(argc, - argv, - GETOPT_STRING, - long_options, - &opt_index); - - if (opt == -1) - break; - - switch (opt) - { - case 0: - break; - - case 't': - input_type=FILEDATA; - break; - - case 'f': - input_type=FILENAME; - break; - - case 'i': - input_type=MIMETYPE; - break; - - case 'm': - output_type=MIMETYPE; - break; - - case 'd': - output_type=DESCRIPTION; - break; - - case 'a': - output_type=ACTION; - break; - - case 'l': - output_type=LAUNCH; - break; - - case 'h': - print_help(argv[0], 1); - exit(0); - - case 'v': - printf(_("%s, version %s\n"), MIMEDB, get_fish_version()); - exit(0); - - case '?': - return 1; - - } - } - - if ((output_type == LAUNCH)&&(input_type==MIMETYPE)) - { - fprintf(stderr, _("%s: Can not launch a mimetype\n"), MIMEDB); - print_help(argv[0], 2); - exit(1); - } - - /* - Loop over all non option arguments and do the specified lookup - */ - - //fprintf( stderr, "Input %d, output %d\n", input_type, output_type ); - - for (i = optind; (i < argc)&&(!error); i++) - { - /* Convert from filename to mimetype, if needed */ - if (input_type == FILENAME) - { - mimetype = xdg_mime_get_mime_type_from_file_name(argv[i]); - } - else if (input_type == FILEDATA) - { - mimetype = xdg_mime_get_mime_type_for_file(argv[i]); - } - else - mimetype = xdg_mime_is_valid_mime_type(argv[i])?argv[i]:0; - - mimetype = xdg_mime_unalias_mime_type(mimetype); - if (!mimetype) - { - fprintf(stderr, _("%s: Could not parse mimetype from argument '%s'\n"), MIMEDB, argv[i]); - error=1; - return 1; - } - - /* - Convert from mimetype to whatever, if needed - */ - switch (output_type) - { - case MIMETYPE: - { - output = (char *)mimetype; - break; - - } - case DESCRIPTION: - { - output = get_description(mimetype); - if (!output) - output = strdup(_("Unknown")); - - break; - } - case ACTION: - { - output = get_action(mimetype); - break; - } - case LAUNCH: - { - /* - There may be more files using the same launcher, we - add them all up in little array_list_ts and launched - them together after all the arguments have been - parsed. - */ - output = 0; - string_list_t &l = launch_hash[mimetype]; - l.push_back(argv[i]); - } - } - - /* - Print the glorious result - */ - if (output) - { - printf("%s\n", output); - if (output != mimetype) - free(output); - } - output = 0; - } - - /* - Perform the actual launching - */ - if (output_type == LAUNCH && !error) - { - for (launch_hash_t::iterator iter = launch_hash.begin(); iter != launch_hash.end(); ++iter) - { - const char *mimetype = iter->first.c_str(); - string_list_t &files = iter->second; - - char *launcher = get_action(mimetype); - - if (launcher) - { - launch(launcher, files, 0); - free(launcher); - } - } - } - - if (launch_buff) - free(launch_buff); - - if (start_re) - { - regfree(start_re); - regfree(stop_re); - free(start_re); - free(stop_re); - } - - xdg_mime_shutdown(); - - return error; -} diff --git a/share/completions/mimedb.fish b/share/completions/mimedb.fish deleted file mode 100644 index 1aa1895a..00000000 --- a/share/completions/mimedb.fish +++ /dev/null @@ -1,9 +0,0 @@ -complete -c mimedb -s t -l input-file-data --description "Input is a file, use name and contents to determine mimetype" -complete -c mimedb -s f -l input-filename --description "Input is a file, use name to determine mimetype" -complete -c mimedb -s i -l input-mime --description "Input is a mimetype" -complete -c mimedb -s m -l output-mime --description "Output mimetype" -complete -c mimedb -s d -l output-description --description "Output description of mimetype" -complete -c mimedb -s a -l output-action --description "Output default action for mimetype" -complete -c mimedb -s l -l launch --description "Launch default action for each file" -complete -c mimedb -s h -l help --description "Display help and exit" -complete -c mimedb -s v -l version --description "Display version and exit" diff --git a/share/functions/mimedb.fish b/share/functions/mimedb.fish deleted file mode 100644 index 3ed24c22..00000000 --- a/share/functions/mimedb.fish +++ /dev/null @@ -1,12 +0,0 @@ -# Wrap mimedb in a function so it does not have to be found in PATH -# But only if it's installed -if test -x $__fish_bin_dir/mimedb - eval "function mimedb --description 'Look up file information via the mimedb database' - \"$__fish_bin_dir/mimedb\" \$argv - end" -else - function mimedb --description 'Look up file information via the mimedb database' - # Create a function that simply fails, because mimedb not installed - return 1 - end -end diff --git a/xdgmime.cpp b/xdgmime.cpp deleted file mode 100644 index 633d0b0a..00000000 --- a/xdgmime.cpp +++ /dev/null @@ -1,722 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003,2004 Red Hat, Inc. - * Copyright (C) 2003,2004 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xdgmime.h" -#include "xdgmimeint.h" -#include "xdgmimeglob.h" -#include "xdgmimemagic.h" -#include "xdgmimealias.h" -#include "xdgmimeparent.h" -#include -#include -#include -#include -#include -#include -#include - -typedef struct XdgDirTimeList XdgDirTimeList; -typedef struct XdgCallbackList XdgCallbackList; - -static int need_reread = TRUE; -static time_t last_stat_time = 0; - -static XdgGlobHash *global_hash = NULL; -static XdgMimeMagic *global_magic = NULL; -static XdgAliasList *alias_list = NULL; -static XdgParentList *parent_list = NULL; -static XdgDirTimeList *dir_time_list = NULL; -static XdgCallbackList *callback_list = NULL; -const char *xdg_mime_type_unknown = "application/octet-stream"; - - -enum -{ - XDG_CHECKED_UNCHECKED, - XDG_CHECKED_VALID, - XDG_CHECKED_INVALID -}; - -struct XdgDirTimeList -{ - time_t mtime; - char *directory_name; - int checked; - XdgDirTimeList *next; -}; - -struct XdgCallbackList -{ - XdgCallbackList *next; - XdgCallbackList *prev; - int callback_id; - XdgMimeCallback callback; - void *data; - XdgMimeDestroy destroy; -}; - -/* Function called by xdg_run_command_on_dirs. If it returns TRUE, further - * directories aren't looked at */ -typedef int (*XdgDirectoryFunc)(const char *directory, - void *user_data); - -static XdgDirTimeList * -xdg_dir_time_list_new(void) -{ - XdgDirTimeList *retval; - - retval = (XdgDirTimeList *)calloc(1, sizeof(XdgDirTimeList)); - retval->checked = XDG_CHECKED_UNCHECKED; - - return retval; -} - -static void -xdg_dir_time_list_free(XdgDirTimeList *list) -{ - XdgDirTimeList *next; - - while (list) - { - next = list->next; - free(list->directory_name); - free(list); - list = next; - } -} - -static int -xdg_mime_init_from_directory(const char *directory) -{ - char *file_name; - struct stat st; - XdgDirTimeList *list; - - assert(directory != NULL); - - file_name = (char *)malloc(strlen(directory) + strlen("/mime/globs") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/globs"); - if (stat(file_name, &st) == 0) - { - _xdg_mime_glob_read_from_file(global_hash, file_name); - - list = xdg_dir_time_list_new(); - list->directory_name = file_name; - list->mtime = st.st_mtime; - list->next = dir_time_list; - dir_time_list = list; - } - else - { - free(file_name); - } - - file_name = (char *)malloc(strlen(directory) + strlen("/mime/magic") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/magic"); - if (stat(file_name, &st) == 0) - { - _xdg_mime_magic_read_from_file(global_magic, file_name); - - list = xdg_dir_time_list_new(); - list->directory_name = file_name; - list->mtime = st.st_mtime; - list->next = dir_time_list; - dir_time_list = list; - } - else - { - free(file_name); - } - - file_name = (char *)malloc(strlen(directory) + strlen("/mime/aliases") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/aliases"); - _xdg_mime_alias_read_from_file(alias_list, file_name); - free(file_name); - - file_name = (char *)malloc(strlen(directory) + strlen("/mime/subclasses") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/subclasses"); - _xdg_mime_parent_read_from_file(parent_list, file_name); - free(file_name); - - return FALSE; /* Keep processing */ -} - -/* Runs a command on all the directories in the search path */ -static void -xdg_run_command_on_dirs(XdgDirectoryFunc func, - void *user_data) -{ - const char *xdg_data_home; - const char *xdg_data_dirs; - const char *ptr; - - xdg_data_home = getenv("XDG_DATA_HOME"); - if (xdg_data_home) - { - if ((func)(xdg_data_home, user_data)) - return; - } - else - { - const char *home; - - home = getenv("HOME"); - if (home != NULL) - { - char *guessed_xdg_home; - int stop_processing; - - guessed_xdg_home = (char *)malloc(strlen(home) + strlen("/.local/share/") + 1); - strcpy(guessed_xdg_home, home); - strcat(guessed_xdg_home, "/.local/share/"); - stop_processing = (func)(guessed_xdg_home, user_data); - free(guessed_xdg_home); - - if (stop_processing) - return; - } - } - - xdg_data_dirs = getenv("XDG_DATA_DIRS"); - if (xdg_data_dirs == NULL) - xdg_data_dirs = "/usr/local/share/:/usr/share/"; - - ptr = xdg_data_dirs; - - while (*ptr != '\000') - { - const char *end_ptr; - char *dir; - int len; - int stop_processing; - - end_ptr = ptr; - while (*end_ptr != ':' && *end_ptr != '\000') - end_ptr ++; - - if (end_ptr == ptr) - { - ptr++; - continue; - } - - if (*end_ptr == ':') - len = end_ptr - ptr; - else - len = end_ptr - ptr + 1; - dir = (char *)malloc(len + 1); - strncpy(dir, ptr, len); - dir[len] = '\0'; - stop_processing = (func)(dir, user_data); - free(dir); - - if (stop_processing) - return; - - ptr = end_ptr; - } -} - -/* Checks file_path to make sure it has the same mtime as last time it was - * checked. If it has a different mtime, or if the file doesn't exist, it - * returns FALSE. - * - * FIXME: This doesn't protect against permission changes. - */ -static int -xdg_check_file(const char *file_path) -{ - struct stat st; - - /* If the file exists */ - if (stat(file_path, &st) == 0) - { - XdgDirTimeList *list; - - for (list = dir_time_list; list; list = list->next) - { - if (! strcmp(list->directory_name, file_path) && - st.st_mtime == list->mtime) - { - if (list->checked == XDG_CHECKED_UNCHECKED) - list->checked = XDG_CHECKED_VALID; - else if (list->checked == XDG_CHECKED_VALID) - list->checked = XDG_CHECKED_INVALID; - - return (list->checked != XDG_CHECKED_VALID); - } - } - return TRUE; - } - - return FALSE; -} - -static int -xdg_check_dir(const char *directory, - int *invalid_dir_list) -{ - int invalid; - char *file_name; - - assert(directory != NULL); - - /* Check the globs file */ - file_name = (char *)malloc(strlen(directory) + strlen("/mime/globs") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/globs"); - invalid = xdg_check_file(file_name); - free(file_name); - if (invalid) - { - *invalid_dir_list = TRUE; - return TRUE; - } - - /* Check the magic file */ - file_name = (char *)malloc(strlen(directory) + strlen("/mime/magic") + 1); - strcpy(file_name, directory); - strcat(file_name, "/mime/magic"); - invalid = xdg_check_file(file_name); - free(file_name); - if (invalid) - { - *invalid_dir_list = TRUE; - return TRUE; - } - - return FALSE; /* Keep processing */ -} - -/* Walks through all the mime files stat()ing them to see if they've changed. - * Returns TRUE if they have. */ -static int -xdg_check_dirs(void) -{ - XdgDirTimeList *list; - int invalid_dir_list = FALSE; - - for (list = dir_time_list; list; list = list->next) - list->checked = XDG_CHECKED_UNCHECKED; - - xdg_run_command_on_dirs((XdgDirectoryFunc) xdg_check_dir, - &invalid_dir_list); - - if (invalid_dir_list) - return TRUE; - - for (list = dir_time_list; list; list = list->next) - { - if (list->checked != XDG_CHECKED_VALID) - return TRUE; - } - - return FALSE; -} - -/* We want to avoid stat()ing on every single mime call, so we only look for - * newer files every 5 seconds. This will return TRUE if we need to reread the - * mime data from disk. - */ -static int -xdg_check_time_and_dirs(void) -{ - struct timeval tv; - time_t current_time; - int retval = FALSE; - - gettimeofday(&tv, NULL); - current_time = tv.tv_sec; - - if (current_time >= last_stat_time + 5) - { - retval = xdg_check_dirs(); - last_stat_time = current_time; - } - - return retval; -} - -/* Called in every public function. It reloads the hash function if need be. - */ -static void -xdg_mime_init(void) -{ - if (xdg_check_time_and_dirs()) - { - xdg_mime_shutdown(); - } - - if (need_reread) - { - global_hash = _xdg_glob_hash_new(); - global_magic = _xdg_mime_magic_new(); - alias_list = _xdg_mime_alias_list_new(); - parent_list = _xdg_mime_parent_list_new(); - - xdg_run_command_on_dirs((XdgDirectoryFunc) xdg_mime_init_from_directory, - NULL); - - need_reread = FALSE; - } -} - -const char * -xdg_mime_get_mime_type_for_data(const void *data, - size_t len) -{ - const char *mime_type; - - xdg_mime_init(); - - mime_type = _xdg_mime_magic_lookup_data(global_magic, data, len); - - if (mime_type) - return mime_type; - - return XDG_MIME_TYPE_UNKNOWN; -} - -const char * -xdg_mime_get_mime_type_for_file(const char *file_name) -{ - const char *mime_type; - FILE *file; - unsigned char *data; - int max_extent; - int bytes_read; - struct stat statbuf; - const char *base_name; - - if (file_name == NULL) - return NULL; - if (! _xdg_utf8_validate(file_name)) - return NULL; - - xdg_mime_init(); - - base_name = _xdg_get_base_name(file_name); - mime_type = xdg_mime_get_mime_type_from_file_name(base_name); - - if (mime_type != XDG_MIME_TYPE_UNKNOWN) - return mime_type; - - if (stat(file_name, &statbuf) != 0) - return XDG_MIME_TYPE_UNKNOWN; - - if (!S_ISREG(statbuf.st_mode)) - return XDG_MIME_TYPE_UNKNOWN; - - /* FIXME: Need to make sure that max_extent isn't totally broken. This could - * be large and need getting from a stream instead of just reading it all - * in. */ - max_extent = _xdg_mime_magic_get_buffer_extents(global_magic); - data = (unsigned char *)malloc(max_extent); - if (data == NULL) - return XDG_MIME_TYPE_UNKNOWN; - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - file = fopen(file_name, "r"); - if (file == NULL) - { - free(data); - return XDG_MIME_TYPE_UNKNOWN; - } - - bytes_read = fread(data, 1, max_extent, file); - if (ferror(file)) - { - free(data); - fclose(file); - return XDG_MIME_TYPE_UNKNOWN; - } - - mime_type = _xdg_mime_magic_lookup_data(global_magic, data, bytes_read); - - free(data); - fclose(file); - - if (mime_type) - return mime_type; - - return XDG_MIME_TYPE_UNKNOWN; -} - -const char * -xdg_mime_get_mime_type_from_file_name(const char *file_name) -{ - const char *mime_type; - - xdg_mime_init(); - - mime_type = _xdg_glob_hash_lookup_file_name(global_hash, file_name); - if (mime_type) - return mime_type; - else - return XDG_MIME_TYPE_UNKNOWN; -} - -int -xdg_mime_is_valid_mime_type(const char *mime_type) -{ - /* FIXME: We should make this a better test - */ - return _xdg_utf8_validate(mime_type); -} - -void -xdg_mime_shutdown(void) -{ - XdgCallbackList *list; - - /* FIXME: Need to make this (and the whole library) thread safe */ - if (dir_time_list) - { - xdg_dir_time_list_free(dir_time_list); - dir_time_list = NULL; - } - - if (global_hash) - { - _xdg_glob_hash_free(global_hash); - global_hash = NULL; - } - if (global_magic) - { - _xdg_mime_magic_free(global_magic); - global_magic = NULL; - } - - if (alias_list) - { - _xdg_mime_alias_list_free(alias_list); - alias_list = NULL; - } - - if (parent_list) - { - _xdg_mime_parent_list_free(parent_list); - } - - - for (list = callback_list; list; list = list->next) - (list->callback)(list->data); - - need_reread = TRUE; -} - -int -xdg_mime_get_max_buffer_extents(void) -{ - xdg_mime_init(); - - return _xdg_mime_magic_get_buffer_extents(global_magic); -} - -const char * -xdg_mime_unalias_mime_type(const char *mime_type) -{ - const char *lookup; - - xdg_mime_init(); - - if ((lookup = _xdg_mime_alias_list_lookup(alias_list, mime_type)) != NULL) - return lookup; - - return mime_type; -} - -int -xdg_mime_mime_type_equal(const char *mime_a, - const char *mime_b) -{ - const char *unalias_a, *unalias_b; - - xdg_mime_init(); - - unalias_a = xdg_mime_unalias_mime_type(mime_a); - unalias_b = xdg_mime_unalias_mime_type(mime_b); - - if (strcmp(unalias_a, unalias_b) == 0) - return 1; - - return 0; -} - -int -xdg_mime_media_type_equal(const char *mime_a, - const char *mime_b) -{ - char *sep; - - xdg_mime_init(); - - sep = const_cast(strchr(mime_a, '/')); - - if (sep && strncmp(mime_a, mime_b, sep - mime_a + 1) == 0) - return 1; - - return 0; -} - -#if 0 -static int -xdg_mime_is_super_type(const char *mime) -{ - int length; - const char *type; - - length = strlen(mime); - type = &(mime[length - 2]); - - if (strcmp(type, "/*") == 0) - return 1; - - return 0; -} -#endif - -int -xdg_mime_mime_type_subclass(const char *mime, - const char *base) -{ - const char *umime, *ubase; - const char **parents; - - xdg_mime_init(); - - umime = xdg_mime_unalias_mime_type(mime); - ubase = xdg_mime_unalias_mime_type(base); - - if (strcmp(umime, ubase) == 0) - return 1; - -#if 0 - /* Handle supertypes */ - if (xdg_mime_is_super_type(ubase) && - xdg_mime_media_type_equal(umime, ubase)) - return 1; -#endif - - /* Handle special cases text/plain and application/octet-stream */ - if (strcmp(ubase, "text/plain") == 0 && - strncmp(umime, "text/", 5) == 0) - return 1; - - if (strcmp(ubase, "application/octet-stream") == 0) - return 1; - - parents = _xdg_mime_parent_list_lookup(parent_list, umime); - for (; parents && *parents; parents++) - { - if (xdg_mime_mime_type_subclass(*parents, ubase)) - return 1; - } - - return 0; -} - -const char ** -xdg_mime_get_mime_parents(const char *mime) -{ - const char *umime; - - xdg_mime_init(); - - umime = xdg_mime_unalias_mime_type(mime); - - return _xdg_mime_parent_list_lookup(parent_list, umime); -} - -void -xdg_mime_dump(void) -{ - printf("*** ALIASES ***\n\n"); - _xdg_mime_alias_list_dump(alias_list); - printf("\n*** PARENTS ***\n\n"); - _xdg_mime_parent_list_dump(parent_list); -} - - -/* Registers a function to be called every time the mime database reloads its files - */ -int -xdg_mime_register_reload_callback(XdgMimeCallback callback, - void *data, - XdgMimeDestroy destroy) -{ - XdgCallbackList *list_el; - static int callback_id = 1; - - /* Make a new list element */ - list_el = (XdgCallbackList *)calloc(1, sizeof(XdgCallbackList)); - list_el->callback_id = callback_id; - list_el->callback = callback; - list_el->data = data; - list_el->destroy = destroy; - list_el->next = callback_list; - if (list_el->next) - list_el->next->prev = list_el; - - callback_list = list_el; - callback_id ++; - - return callback_id - 1; -} - -void -xdg_mime_remove_callback(int callback_id) -{ - XdgCallbackList *list; - - for (list = callback_list; list; list = list->next) - { - if (list->callback_id == callback_id) - { - if (list->next) - list->next = list->prev; - - if (list->prev) - list->prev->next = list->next; - else - callback_list = list->next; - - /* invoke the destroy handler */ - (list->destroy)(list->data); - free(list); - return; - } - } -} diff --git a/xdgmime.h b/xdgmime.h deleted file mode 100644 index 9c53bb11..00000000 --- a/xdgmime.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmime.h: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - - -#ifndef __XDG_MIME_H__ -#define __XDG_MIME_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef XDG_PREFIX -#define XDG_ENTRY(func) _XDG_ENTRY2(XDG_PREFIX,func) -#define _XDG_ENTRY2(prefix,func) _XDG_ENTRY3(prefix,func) -#define _XDG_ENTRY3(prefix,func) prefix##_##func -#endif - - typedef void (*XdgMimeCallback)(void *user_data); - typedef void (*XdgMimeDestroy)(void *user_data); - - -#ifdef XDG_PREFIX -#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data) -#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file) -#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name) -#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type) -#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal) -#define xdg_mime_media_type_equal XDG_ENTRY(media_type_equal) -#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass) -#define xdg_mime_get_mime_parents XDG_ENTRY(get_mime_parents) -#define xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type) -#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents) -#define xdg_mime_shutdown XDG_ENTRY(shutdown) -#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback) -#define xdg_mime_remove_callback XDG_ENTRY(remove_callback) -#define xdg_mime_type_unknown XDG_ENTRY(type_unknown) -#endif - - extern const char *xdg_mime_type_unknown; -#define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown - - const char *xdg_mime_get_mime_type_for_data(const void *data, - size_t len); - const char *xdg_mime_get_mime_type_for_file(const char *file_name); - const char *xdg_mime_get_mime_type_from_file_name(const char *file_name); - int xdg_mime_is_valid_mime_type(const char *mime_type); - int xdg_mime_mime_type_equal(const char *mime_a, - const char *mime_b); - int xdg_mime_media_type_equal(const char *mime_a, - const char *mime_b); - int xdg_mime_mime_type_subclass(const char *mime_a, - const char *mime_b); - const char **xdg_mime_get_mime_parents(const char *mime); - const char *xdg_mime_unalias_mime_type(const char *mime); - int xdg_mime_get_max_buffer_extents(void); - void xdg_mime_shutdown(void); - void xdg_mime_dump(void); - int xdg_mime_register_reload_callback(XdgMimeCallback callback, - void *data, - XdgMimeDestroy destroy); - void xdg_mime_remove_callback(int callback_id); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __XDG_MIME_H__ */ diff --git a/xdgmimealias.cpp b/xdgmimealias.cpp deleted file mode 100644 index e556d4e6..00000000 --- a/xdgmimealias.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimealias.c: Private file. Datastructure for storing the aliases. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 2004 Matthias Clasen - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xdgmimealias.h" -#include "xdgmimeint.h" -#include -#include -#include -#include -#include - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef struct XdgAlias XdgAlias; - -struct XdgAlias -{ - char *alias; - char *mime_type; -}; - -struct XdgAliasList -{ - struct XdgAlias *aliases; - int n_aliases; -}; - -XdgAliasList * -_xdg_mime_alias_list_new(void) -{ - XdgAliasList *list; - - list = (XdgAliasList *)malloc(sizeof(XdgAliasList)); - - list->aliases = NULL; - list->n_aliases = 0; - - return list; -} - -void -_xdg_mime_alias_list_free(XdgAliasList *list) -{ - int i; - - if (list->aliases) - { - for (i = 0; i < list->n_aliases; i++) - { - free(list->aliases[i].alias); - free(list->aliases[i].mime_type); - } - free(list->aliases); - } - free(list); -} - -static int -alias_entry_cmp(const void *v1, const void *v2) -{ - return strcmp(((XdgAlias *)v1)->alias, ((XdgAlias *)v2)->alias); -} - -const char * -_xdg_mime_alias_list_lookup(XdgAliasList *list, - const char *alias) -{ - XdgAlias *entry; - XdgAlias key; - - if (list->n_aliases > 0) - { - key.alias = (char *)alias; - key.mime_type = 0; - - entry = (XdgAlias *)bsearch(&key, list->aliases, list->n_aliases, - sizeof(XdgAlias), alias_entry_cmp); - if (entry) - return entry->mime_type; - } - - return NULL; -} - -void -_xdg_mime_alias_read_from_file(XdgAliasList *list, - const char *file_name) -{ - FILE *file; - char line[255]; - int alloc; - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - file = fopen(file_name, "r"); - - if (file == NULL) - return; - - /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. - * Blah */ - alloc = list->n_aliases + 16; - list->aliases = (XdgAlias *)realloc(list->aliases, alloc * sizeof(XdgAlias)); - while (fgets(line, 255, file) != NULL) - { - char *sep; - if (line[0] == '#') - continue; - - sep = strchr(line, ' '); - if (sep == NULL) - continue; - *(sep++) = '\000'; - sep[strlen(sep) -1] = '\000'; - if (list->n_aliases == alloc) - { - alloc <<= 1; - list->aliases = (XdgAlias *)realloc(list->aliases, - alloc * sizeof(XdgAlias)); - } - list->aliases[list->n_aliases].alias = strdup(line); - list->aliases[list->n_aliases].mime_type = strdup(sep); - list->n_aliases++; - } - list->aliases = (XdgAlias *)realloc(list->aliases, - list->n_aliases * sizeof(XdgAlias)); - - fclose(file); - - if (list->n_aliases > 1) - qsort(list->aliases, list->n_aliases, - sizeof(XdgAlias), alias_entry_cmp); -} - - -void -_xdg_mime_alias_list_dump(XdgAliasList *list) -{ - int i; - - if (list->aliases) - { - for (i = 0; i < list->n_aliases; i++) - { - printf("%s %s\n", - list->aliases[i].alias, - list->aliases[i].mime_type); - } - } -} - - diff --git a/xdgmimealias.h b/xdgmimealias.h deleted file mode 100644 index 13933642..00000000 --- a/xdgmimealias.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimealias.h: Private file. Datastructure for storing the aliases. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 200 Matthias Clasen - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XDG_MIME_ALIAS_H__ -#define __XDG_MIME_ALIAS_H__ - -#include "xdgmime.h" - -typedef struct XdgAliasList XdgAliasList; - -#ifdef XDG_PREFIX -#define _xdg_mime_alias_read_from_file XDG_ENTRY(alias_read_from_file) -#define _xdg_mime_alias_list_new XDG_ENTRY(alias_list_new) -#define _xdg_mime_alias_list_free XDG_ENTRY(alias_list_free) -#define _xdg_mime_alias_list_lookup XDG_ENTRY(alias_list_lookup) -#endif - -void _xdg_mime_alias_read_from_file(XdgAliasList *list, - const char *file_name); -XdgAliasList *_xdg_mime_alias_list_new(void); -void _xdg_mime_alias_list_free(XdgAliasList *list); -const char *_xdg_mime_alias_list_lookup(XdgAliasList *list, - const char *alias); -void _xdg_mime_alias_list_dump(XdgAliasList *list); - -#endif /* __XDG_MIME_ALIAS_H__ */ diff --git a/xdgmimeglob.cpp b/xdgmimeglob.cpp deleted file mode 100644 index 4182f3c9..00000000 --- a/xdgmimeglob.cpp +++ /dev/null @@ -1,473 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimeglob.c: Private file. Datastructure for storing the globs. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xdgmimeglob.h" -#include "xdgmimeint.h" -#include -#include -#include -#include -#include - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef struct XdgGlobHashNode XdgGlobHashNode; -typedef struct XdgGlobList XdgGlobList; - -struct XdgGlobHashNode -{ - xdg_unichar_t character; - const char *mime_type; - XdgGlobHashNode *next; - XdgGlobHashNode *child; -}; -struct XdgGlobList -{ - const char *data; - const char *mime_type; - XdgGlobList *next; -}; - -struct XdgGlobHash -{ - XdgGlobList *literal_list; - XdgGlobHashNode *simple_node; - XdgGlobList *full_list; -}; - - -/* XdgGlobList - */ -static XdgGlobList * -_xdg_glob_list_new(void) -{ - XdgGlobList *new_element; - - new_element = (XdgGlobList *)calloc(1, sizeof(XdgGlobList)); - - return new_element; -} - -/* Frees glob_list and all of it's children */ -static void -_xdg_glob_list_free(XdgGlobList *glob_list) -{ - XdgGlobList *ptr, *next; - - ptr = glob_list; - - while (ptr != NULL) - { - next = ptr->next; - - if (ptr->data) - free((void *) ptr->data); - if (ptr->mime_type) - free((void *) ptr->mime_type); - free(ptr); - - ptr = next; - } -} - -static XdgGlobList * -_xdg_glob_list_append(XdgGlobList *glob_list, - void *data, - const char *mime_type) -{ - XdgGlobList *new_element; - XdgGlobList *tmp_element; - - new_element = _xdg_glob_list_new(); - new_element->data = (const char *)data; - new_element->mime_type = mime_type; - if (glob_list == NULL) - return new_element; - - tmp_element = glob_list; - while (tmp_element->next != NULL) - tmp_element = tmp_element->next; - - tmp_element->next = new_element; - - return glob_list; -} - -#if 0 -static XdgGlobList * -_xdg_glob_list_prepend(XdgGlobList *glob_list, - void *data, - const char *mime_type) -{ - XdgGlobList *new_element; - - new_element = _xdg_glob_list_new(); - new_element->data = data; - new_element->next = glob_list; - new_element->mime_type = mime_type; - - return new_element; -} -#endif - -/* XdgGlobHashNode - */ - -static XdgGlobHashNode * -_xdg_glob_hash_node_new(void) -{ - XdgGlobHashNode *glob_hash_node; - - glob_hash_node = (XdgGlobHashNode *)calloc(1, sizeof(XdgGlobHashNode)); - - return glob_hash_node; -} - -static void -_xdg_glob_hash_node_dump(XdgGlobHashNode *glob_hash_node, - int depth) -{ - int i; - for (i = 0; i < depth; i++) - printf(" "); - - printf("%c", (char)glob_hash_node->character); - if (glob_hash_node->mime_type) - printf(" - %s\n", glob_hash_node->mime_type); - else - printf("\n"); - if (glob_hash_node->child) - _xdg_glob_hash_node_dump(glob_hash_node->child, depth + 1); - if (glob_hash_node->next) - _xdg_glob_hash_node_dump(glob_hash_node->next, depth); -} - -static XdgGlobHashNode * -_xdg_glob_hash_insert_text(XdgGlobHashNode *glob_hash_node, - const char *text, - const char *mime_type) -{ - XdgGlobHashNode *node; - xdg_unichar_t character; - - character = _xdg_utf8_to_ucs4(text); - - if ((glob_hash_node == NULL) || - (character < glob_hash_node->character)) - { - node = _xdg_glob_hash_node_new(); - node->character = character; - node->next = glob_hash_node; - glob_hash_node = node; - } - else if (character == glob_hash_node->character) - { - node = glob_hash_node; - } - else - { - XdgGlobHashNode *prev_node; - int found_node = FALSE; - - /* Look for the first character of text in glob_hash_node, and insert it if we - * have to.*/ - prev_node = glob_hash_node; - node = prev_node->next; - - while (node != NULL) - { - if (character < node->character) - { - node = _xdg_glob_hash_node_new(); - node->character = character; - node->next = prev_node->next; - prev_node->next = node; - - found_node = TRUE; - break; - } - else if (character == node->character) - { - found_node = TRUE; - break; - } - prev_node = node; - node = node->next; - } - - if (! found_node) - { - node = _xdg_glob_hash_node_new(); - node->character = character; - node->next = prev_node->next; - prev_node->next = node; - } - } - - text = _xdg_utf8_next_char(text); - if (*text == '\000') - { - node->mime_type = mime_type; - } - else - { - node->child = _xdg_glob_hash_insert_text(node->child, text, mime_type); - } - return glob_hash_node; -} - -static const char * -_xdg_glob_hash_node_lookup_file_name(XdgGlobHashNode *glob_hash_node, - const char *file_name, - int ignore_case) -{ - XdgGlobHashNode *node; - xdg_unichar_t character; - - if (glob_hash_node == NULL) - return NULL; - - character = _xdg_utf8_to_ucs4(file_name); - if (ignore_case) - character = _xdg_ucs4_to_lower(character); - - for (node = glob_hash_node; node && character >= node->character; node = node->next) - { - if (character == node->character) - { - file_name = _xdg_utf8_next_char(file_name); - if (*file_name == '\000') - return node->mime_type; - else - return _xdg_glob_hash_node_lookup_file_name(node->child, - file_name, - ignore_case); - } - } - return NULL; -} - -const char * -_xdg_glob_hash_lookup_file_name(XdgGlobHash *glob_hash, - const char *file_name) -{ - XdgGlobList *list; - const char *mime_type; - const char *ptr; - /* First, check the literals */ - - assert(file_name != NULL); - - for (list = glob_hash->literal_list; list; list = list->next) - if (strcmp((const char *)list->data, file_name) == 0) - return list->mime_type; - - ptr = strchr(file_name, '.'); - while (ptr != NULL) - { - mime_type = (_xdg_glob_hash_node_lookup_file_name(glob_hash->simple_node, ptr, FALSE)); - if (mime_type != NULL) - return mime_type; - - mime_type = (_xdg_glob_hash_node_lookup_file_name(glob_hash->simple_node, ptr, TRUE)); - if (mime_type != NULL) - return mime_type; - - ptr = strchr(ptr+1, '.'); - } - - /* FIXME: Not UTF-8 safe */ - for (list = glob_hash->full_list; list; list = list->next) - if (fnmatch((const char *)list->data, file_name, 0) == 0) - return list->mime_type; - - return NULL; -} - - - -/* XdgGlobHash - */ - -XdgGlobHash * -_xdg_glob_hash_new(void) -{ - XdgGlobHash *glob_hash; - - glob_hash = (XdgGlobHash *)calloc(1, sizeof(XdgGlobHash)); - - return glob_hash; -} - - -static void -_xdg_glob_hash_free_nodes(XdgGlobHashNode *node) -{ - if (node) - { - if (node->child) - _xdg_glob_hash_free_nodes(node->child); - if (node->next) - _xdg_glob_hash_free_nodes(node->next); - if (node->mime_type) - free((void *) node->mime_type); - free(node); - } -} - -void -_xdg_glob_hash_free(XdgGlobHash *glob_hash) -{ - _xdg_glob_list_free(glob_hash->literal_list); - _xdg_glob_list_free(glob_hash->full_list); - _xdg_glob_hash_free_nodes(glob_hash->simple_node); - free(glob_hash); -} - -XdgGlobType -_xdg_glob_determine_type(const char *glob) -{ - const char *ptr; - int maybe_in_simple_glob = FALSE; - int first_char = TRUE; - - ptr = glob; - - while (*ptr != '\000') - { - if (*ptr == '*' && first_char) - maybe_in_simple_glob = TRUE; - else if (*ptr == '\\' || *ptr == '[' || *ptr == '?' || *ptr == '*') - return XDG_GLOB_FULL; - - first_char = FALSE; - ptr = _xdg_utf8_next_char(ptr); - } - if (maybe_in_simple_glob) - return XDG_GLOB_SIMPLE; - else - return XDG_GLOB_LITERAL; -} - -/* glob must be valid UTF-8 */ -void -_xdg_glob_hash_append_glob(XdgGlobHash *glob_hash, - const char *glob, - const char *mime_type) -{ - XdgGlobType type; - - assert(glob_hash != NULL); - assert(glob != NULL); - - type = _xdg_glob_determine_type(glob); - - switch (type) - { - case XDG_GLOB_LITERAL: - glob_hash->literal_list = _xdg_glob_list_append(glob_hash->literal_list, strdup(glob), strdup(mime_type)); - break; - case XDG_GLOB_SIMPLE: - glob_hash->simple_node = _xdg_glob_hash_insert_text(glob_hash->simple_node, glob + 1, strdup(mime_type)); - break; - case XDG_GLOB_FULL: - glob_hash->full_list = _xdg_glob_list_append(glob_hash->full_list, strdup(glob), strdup(mime_type)); - break; - } -} - -void -_xdg_glob_hash_dump(XdgGlobHash *glob_hash) -{ - XdgGlobList *list; - printf("LITERAL STRINGS\n"); - if (glob_hash->literal_list == NULL) - { - printf(" None\n"); - } - else - { - for (list = glob_hash->literal_list; list; list = list->next) - printf(" %s - %s\n", (char *)list->data, list->mime_type); - } - printf("\nSIMPLE GLOBS\n"); - _xdg_glob_hash_node_dump(glob_hash->simple_node, 4); - - printf("\nFULL GLOBS\n"); - if (glob_hash->full_list == NULL) - { - printf(" None\n"); - } - else - { - for (list = glob_hash->full_list; list; list = list->next) - printf(" %s - %s\n", (char *)list->data, list->mime_type); - } -} - - -void -_xdg_mime_glob_read_from_file(XdgGlobHash *glob_hash, - const char *file_name) -{ - FILE *glob_file; - char line[255]; - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - glob_file = fopen(file_name, "r"); - - if (glob_file == NULL) - return; - - /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. - * Blah */ - while (fgets(line, 255, glob_file) != NULL) - { - char *colon; - if (line[0] == '#') - continue; - - colon = strchr(line, ':'); - if (colon == NULL) - continue; - *(colon++) = '\000'; - colon[strlen(colon) -1] = '\000'; - _xdg_glob_hash_append_glob(glob_hash, colon, line); - } - - fclose(glob_file); -} diff --git a/xdgmimeglob.h b/xdgmimeglob.h deleted file mode 100644 index 136e49a3..00000000 --- a/xdgmimeglob.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimeglob.h: Private file. Datastructure for storing the globs. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XDG_MIME_GLOB_H__ -#define __XDG_MIME_GLOB_H__ - -#include "xdgmime.h" - -typedef struct XdgGlobHash XdgGlobHash; - -typedef enum -{ - XDG_GLOB_LITERAL, /* Makefile */ - XDG_GLOB_SIMPLE, /* *.gif */ - XDG_GLOB_FULL /* x*.[ch] */ -} XdgGlobType; - - -#ifdef XDG_PREFIX -#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file) -#define _xdg_glob_hash_new XDG_ENTRY(hash_new) -#define _xdg_glob_hash_free XDG_ENTRY(hash_free) -#define _xdg_glob_hash_lookup_file_name XDG_ENTRY(hash_lookup_file_name) -#define _xdg_glob_hash_append_glob XDG_ENTRY(hash_append_glob) -#define _xdg_glob_determine_type XDG_ENTRY(determine_type) -#define _xdg_glob_hash_dump XDG_ENTRY(hash_dump) -#endif - -void _xdg_mime_glob_read_from_file(XdgGlobHash *glob_hash, - const char *file_name); -XdgGlobHash *_xdg_glob_hash_new(void); -void _xdg_glob_hash_free(XdgGlobHash *glob_hash); -const char *_xdg_glob_hash_lookup_file_name(XdgGlobHash *glob_hash, - const char *text); -void _xdg_glob_hash_append_glob(XdgGlobHash *glob_hash, - const char *glob, - const char *mime_type); -XdgGlobType _xdg_glob_determine_type(const char *glob); -void _xdg_glob_hash_dump(XdgGlobHash *glob_hash); - -#endif /* __XDG_MIME_GLOB_H__ */ diff --git a/xdgmimeint.cpp b/xdgmimeint.cpp deleted file mode 100644 index 7e8ea31c..00000000 --- a/xdgmimeint.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimeint.c: Internal defines and functions. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xdgmimeint.h" -#include -#include - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -static const char _xdg_utf8_skip_data[256] = -{ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 -}; - -const char * const _xdg_utf8_skip = _xdg_utf8_skip_data; - - - -/* Returns the number of unprocessed characters. */ -xdg_unichar_t -_xdg_utf8_to_ucs4(const char *source) -{ - xdg_unichar_t ucs32; - if (!(*source & 0x80)) - { - ucs32 = *source; - } - else - { - int bytelength = 0; - xdg_unichar_t result; - if (!(*source & 0x40)) - { - ucs32 = *source; - } - else - { - if (!(*source & 0x20)) - { - result = *source++ & 0x1F; - bytelength = 2; - } - else if (!(*source & 0x10)) - { - result = *source++ & 0x0F; - bytelength = 3; - } - else if (!(*source & 0x08)) - { - result = *source++ & 0x07; - bytelength = 4; - } - else if (!(*source & 0x04)) - { - result = *source++ & 0x03; - bytelength = 5; - } - else if (!(*source & 0x02)) - { - result = *source++ & 0x01; - bytelength = 6; - } - else - { - result = *source++; - bytelength = 1; - } - - for (bytelength --; bytelength > 0; bytelength --) - { - result <<= 6; - result |= *source++ & 0x3F; - } - ucs32 = result; - } - } - return ucs32; -} - - -/* hullo. this is great code. don't rewrite it */ - -xdg_unichar_t -_xdg_ucs4_to_lower(xdg_unichar_t source) -{ - /* FIXME: Do a real to_upper sometime */ - /* CaseFolding-3.2.0.txt has a table of rules. */ - if ((source & 0xFF) == source) - return (xdg_unichar_t) tolower((unsigned char) source); - return source; -} - -int -_xdg_utf8_validate(const char *source) -{ - /* FIXME: actually write */ - return TRUE; -} - -const char * -_xdg_get_base_name(const char *file_name) -{ - const char *base_name; - - if (file_name == NULL) - return NULL; - - base_name = strrchr(file_name, '/'); - - if (base_name == NULL) - return file_name; - else - return base_name + 1; -} diff --git a/xdgmimeint.h b/xdgmimeint.h deleted file mode 100644 index 5e825dab..00000000 --- a/xdgmimeint.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimeint.h: Internal defines and functions. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XDG_MIME_INT_H__ -#define __XDG_MIME_INT_H__ - -#include "xdgmime.h" - - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -/* FIXME: Needs to be configure check */ -typedef unsigned int xdg_unichar_t; -typedef unsigned char xdg_uchar8_t; -typedef unsigned short xdg_uint16_t; -typedef unsigned int xdg_uint32_t; - -#ifdef XDG_PREFIX -#define _xdg_utf8_skip XDG_ENTRY(utf8_skip) -#define _xdg_utf8_to_ucs4 XDG_ENTRY(utf8_to_ucs4) -#define _xdg_ucs4_to_lower XDG_ENTRY(ucs4_to_lower) -#define _xdg_utf8_validate XDG_ENTRY(utf8_validate) -#define _xdg_get_base_name XDG_ENTRY(get_ase_name) -#endif - -#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8)) - -#define SWAP_BE32_TO_LE32(val) (xdg_uint32_t)((((xdg_uint32_t)(val) & 0xFF000000U) >> 24) | \ - (((xdg_uint32_t)(val) & 0x00FF0000U) >> 8) | \ - (((xdg_uint32_t)(val) & 0x0000FF00U) << 8) | \ - (((xdg_uint32_t)(val) & 0x000000FFU) << 24)) -/* UTF-8 utils - */ -extern const char *const _xdg_utf8_skip; -#define _xdg_utf8_next_char(p) (char *)((p) + _xdg_utf8_skip[*(unsigned char *)(p)]) -#define _xdg_utf8_char_size(p) (int) (_xdg_utf8_skip[*(unsigned char *)(p)]) - -xdg_unichar_t _xdg_utf8_to_ucs4(const char *source); -xdg_unichar_t _xdg_ucs4_to_lower(xdg_unichar_t source); -int _xdg_utf8_validate(const char *source); -const char *_xdg_get_base_name(const char *file_name); - -#endif /* __XDG_MIME_INT_H__ */ diff --git a/xdgmimemagic.cpp b/xdgmimemagic.cpp deleted file mode 100644 index b906685e..00000000 --- a/xdgmimemagic.cpp +++ /dev/null @@ -1,790 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimemagic.: Private file. Datastructure for storing magic files. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "xdgmimemagic.h" -#include "xdgmimeint.h" -#include -#include -#include -#include -#include -#include - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef struct XdgMimeMagicMatch XdgMimeMagicMatch; -typedef struct XdgMimeMagicMatchlet XdgMimeMagicMatchlet; - -typedef enum -{ - XDG_MIME_MAGIC_SECTION, - XDG_MIME_MAGIC_MAGIC, - XDG_MIME_MAGIC_ERROR, - XDG_MIME_MAGIC_EOF -} XdgMimeMagicState; - -struct XdgMimeMagicMatch -{ - const char *mime_type; - int priority; - XdgMimeMagicMatchlet *matchlet; - XdgMimeMagicMatch *next; -}; - - -struct XdgMimeMagicMatchlet -{ - int indent; - int offset; - unsigned int value_length; - unsigned char *value; - unsigned char *mask; - unsigned int range_length; - unsigned int word_size; - XdgMimeMagicMatchlet *next; -}; - - -struct XdgMimeMagic -{ - XdgMimeMagicMatch *match_list; - int max_extent; -}; - -static XdgMimeMagicMatch * -_xdg_mime_magic_match_new(void) -{ - return (XdgMimeMagicMatch *)calloc(1, sizeof(XdgMimeMagicMatch)); -} - - -static XdgMimeMagicMatchlet * -_xdg_mime_magic_matchlet_new(void) -{ - XdgMimeMagicMatchlet *matchlet; - - matchlet = (XdgMimeMagicMatchlet *)malloc(sizeof(XdgMimeMagicMatchlet)); - - matchlet->indent = 0; - matchlet->offset = 0; - matchlet->value_length = 0; - matchlet->value = NULL; - matchlet->mask = NULL; - matchlet->range_length = 1; - matchlet->word_size = 1; - matchlet->next = NULL; - - return matchlet; -} - - -static void -_xdg_mime_magic_matchlet_free(XdgMimeMagicMatchlet *mime_magic_matchlet) -{ - if (mime_magic_matchlet) - { - if (mime_magic_matchlet->next) - _xdg_mime_magic_matchlet_free(mime_magic_matchlet->next); - if (mime_magic_matchlet->value) - free(mime_magic_matchlet->value); - if (mime_magic_matchlet->mask) - free(mime_magic_matchlet->mask); - free(mime_magic_matchlet); - } -} - - -/* Frees mime_magic_match and the remainder of its list - */ -static void -_xdg_mime_magic_match_free(XdgMimeMagicMatch *mime_magic_match) -{ - XdgMimeMagicMatch *ptr, *next; - - ptr = mime_magic_match; - while (ptr) - { - next = ptr->next; - - if (ptr->mime_type) - free((void *) ptr->mime_type); - if (ptr->matchlet) - _xdg_mime_magic_matchlet_free(ptr->matchlet); - free(ptr); - - ptr = next; - } -} - -/* Reads in a hunk of data until a newline character or a '\000' is hit. The - * returned string is null terminated, and doesn't include the newline. - */ -static char * -_xdg_mime_magic_read_to_newline(FILE *magic_file, - int *end_of_file) -{ - char *retval; - int c; - int len, pos; - - len = 128; - pos = 0; - retval = (char *)malloc(len); - *end_of_file = FALSE; - - while (TRUE) - { - c = getc_unlocked(magic_file); - if (c == EOF) - { - *end_of_file = TRUE; - break; - } - if (c == '\n' || c == '\000') - break; - retval[pos++] = (char) c; - if (pos % 128 == 127) - { - len = len + 128; - char *tmp = (char *)realloc(retval, len); - if (tmp == NULL) - { - free(retval); - return NULL; - } - retval = tmp; - } - } - - retval[pos] = '\000'; - return retval; -} - -/* Returns the number read from the file, or -1 if no number could be read. - */ -static int -_xdg_mime_magic_read_a_number(FILE *magic_file, - int *end_of_file) -{ - /* LONG_MAX is about 20 characters on my system */ -#define MAX_NUMBER_SIZE 30 - char number_string[MAX_NUMBER_SIZE + 1]; - int pos = 0; - int c; - long retval = -1; - - while (TRUE) - { - c = getc_unlocked(magic_file); - - if (c == EOF) - { - *end_of_file = TRUE; - break; - } - if (! isdigit(c)) - { - ungetc(c, magic_file); - break; - } - number_string[pos] = (char) c; - pos++; - if (pos == MAX_NUMBER_SIZE) - break; - } - if (pos > 0) - { - number_string[pos] = '\000'; - errno = 0; - retval = strtol(number_string, NULL, 10); - - if ((retval < INT_MIN) || (retval > INT_MAX) || (errno != 0)) - return -1; - } - - return retval; -} - -/* Headers are of the format: - * [:] - */ -static XdgMimeMagicState -_xdg_mime_magic_parse_header(FILE *magic_file, XdgMimeMagicMatch *match) -{ - int c; - char *buffer; - char *end_ptr; - int end_of_file = 0; - - assert(magic_file != NULL); - assert(match != NULL); - - c = getc_unlocked(magic_file); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - if (c != '[') - return XDG_MIME_MAGIC_ERROR; - - match->priority = _xdg_mime_magic_read_a_number(magic_file, &end_of_file); - if (end_of_file) - return XDG_MIME_MAGIC_EOF; - if (match->priority == -1) - return XDG_MIME_MAGIC_ERROR; - - c = getc_unlocked(magic_file); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - if (c != ':') - return XDG_MIME_MAGIC_ERROR; - - buffer = _xdg_mime_magic_read_to_newline(magic_file, &end_of_file); - if (end_of_file) - { - free(buffer); - return XDG_MIME_MAGIC_EOF; - } - - end_ptr = buffer; - while (*end_ptr != ']' && *end_ptr != '\000' && *end_ptr != '\n') - end_ptr++; - if (*end_ptr != ']') - { - free(buffer); - return XDG_MIME_MAGIC_ERROR; - } - *end_ptr = '\000'; - - match->mime_type = strdup(buffer); - free(buffer); - - return XDG_MIME_MAGIC_MAGIC; -} - -static XdgMimeMagicState -_xdg_mime_magic_parse_error(FILE *magic_file) -{ - int c; - - while (1) - { - c = getc_unlocked(magic_file); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - if (c == '\n') - return XDG_MIME_MAGIC_SECTION; - } -} - -/* Headers are of the format: - * [ indent ] ">" start-offset "=" value - * [ "&" mask ] [ "~" word-size ] [ "+" range-length ] "\n" - */ -static XdgMimeMagicState -_xdg_mime_magic_parse_magic_line(FILE *magic_file, - XdgMimeMagicMatch *match) -{ - XdgMimeMagicMatchlet *matchlet; - int c; - int end_of_file; - int indent = 0; - size_t bytes_read; - - assert(magic_file != NULL); - - /* Sniff the buffer to make sure it's a valid line */ - c = getc_unlocked(magic_file); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - else if (c == '[') - { - ungetc(c, magic_file); - return XDG_MIME_MAGIC_SECTION; - } - else if (c == '\n') - return XDG_MIME_MAGIC_MAGIC; - - /* At this point, it must be a digit or a '>' */ - end_of_file = FALSE; - if (isdigit(c)) - { - ungetc(c, magic_file); - indent = _xdg_mime_magic_read_a_number(magic_file, &end_of_file); - if (end_of_file) - return XDG_MIME_MAGIC_EOF; - if (indent == -1) - return XDG_MIME_MAGIC_ERROR; - c = getc_unlocked(magic_file); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - } - - if (c != '>') - return XDG_MIME_MAGIC_ERROR; - - matchlet = _xdg_mime_magic_matchlet_new(); - matchlet->indent = indent; - matchlet->offset = _xdg_mime_magic_read_a_number(magic_file, &end_of_file); - if (end_of_file) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - if (matchlet->offset == -1) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - c = getc_unlocked(magic_file); - if (c == EOF) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - else if (c != '=') - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - - /* Next two bytes determine how long the value is */ - matchlet->value_length = 0; - c = getc_unlocked(magic_file); - if (c == EOF) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - matchlet->value_length = c & 0xFF; - matchlet->value_length = matchlet->value_length << 8; - - c = getc_unlocked(magic_file); - if (c == EOF) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - matchlet->value_length = matchlet->value_length + (c & 0xFF); - - matchlet->value = (unsigned char *)malloc(matchlet->value_length); - - /* OOM */ - if (matchlet->value == NULL) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - bytes_read = fread(matchlet->value, 1, matchlet->value_length, magic_file); - if (bytes_read != matchlet->value_length) - { - _xdg_mime_magic_matchlet_free(matchlet); - if (feof(magic_file)) - return XDG_MIME_MAGIC_EOF; - else - return XDG_MIME_MAGIC_ERROR; - } - - c = getc_unlocked(magic_file); - if (c == '&') - { - matchlet->mask = (unsigned char *)malloc(matchlet->value_length); - /* OOM */ - if (matchlet->mask == NULL) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - bytes_read = fread(matchlet->mask, 1, matchlet->value_length, magic_file); - if (bytes_read != matchlet->value_length) - { - _xdg_mime_magic_matchlet_free(matchlet); - if (feof(magic_file)) - return XDG_MIME_MAGIC_EOF; - else - return XDG_MIME_MAGIC_ERROR; - } - c = getc_unlocked(magic_file); - } - - if (c == '~') - { - matchlet->word_size = _xdg_mime_magic_read_a_number(magic_file, &end_of_file); - if (end_of_file) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - if (matchlet->word_size != 0 && - matchlet->word_size != 1 && - matchlet->word_size != 2 && - matchlet->word_size != 4) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - c = getc_unlocked(magic_file); - } - - if (c == '+') - { - matchlet->range_length = _xdg_mime_magic_read_a_number(magic_file, &end_of_file); - if (end_of_file) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_EOF; - } - if (matchlet->range_length == (unsigned int)-1) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - c = getc_unlocked(magic_file); - } - - - if (c == '\n') - { - /* We clean up the matchlet, byte swapping if needed */ - if (matchlet->word_size > 1) - { - size_t i; - if (matchlet->value_length % matchlet->word_size != 0) - { - _xdg_mime_magic_matchlet_free(matchlet); - return XDG_MIME_MAGIC_ERROR; - } - /* FIXME: need to get this defined in a style file */ -#if LITTLE_ENDIAN - for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size) - { - if (matchlet->word_size == 2) - *((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16(*((xdg_uint16_t *)(matchlet->value + i))); - else if (matchlet->word_size == 4) - *((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32(*((xdg_uint32_t *)(matchlet->value + i))); - if (matchlet->mask) - { - if (matchlet->word_size == 2) - *((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16(*((xdg_uint16_t *)(matchlet->mask + i))); - else if (matchlet->word_size == 4) - *((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32(*((xdg_uint32_t *)(matchlet->mask + i))); - - } - } -#endif - } - - matchlet->next = match->matchlet; - match->matchlet = matchlet; - - - return XDG_MIME_MAGIC_MAGIC; - } - - _xdg_mime_magic_matchlet_free(matchlet); - if (c == EOF) - return XDG_MIME_MAGIC_EOF; - - return XDG_MIME_MAGIC_ERROR; -} - -static int -_xdg_mime_magic_matchlet_compare_to_data(XdgMimeMagicMatchlet *matchlet, - const void *data, - size_t len) -{ - size_t i, j; - - for (i = matchlet->offset; i <= matchlet->offset + matchlet->range_length; i++) - { - int valid_matchlet = TRUE; - - if (i + matchlet->value_length > len) - return FALSE; - - if (matchlet->mask) - { - for (j = 0; j < matchlet->value_length; j++) - { - if ((matchlet->value[j] & matchlet->mask[j]) != - ((((unsigned char *) data)[j + i]) & matchlet->mask[j])) - { - valid_matchlet = FALSE; - break; - } - } - } - else - { - for (j = 0; j < matchlet->value_length; j++) - { - if (matchlet->value[j] != ((unsigned char *) data)[j + i]) - { - valid_matchlet = FALSE; - break; - } - } - } - if (valid_matchlet) - return TRUE; - } - return FALSE; -} - -static int -_xdg_mime_magic_matchlet_compare_level(XdgMimeMagicMatchlet *matchlet, - const void *data, - size_t len, - int indent) -{ - while ((matchlet != NULL) && (matchlet->indent == indent)) - { - if (_xdg_mime_magic_matchlet_compare_to_data(matchlet, data, len)) - { - if ((matchlet->next == NULL) || - (matchlet->next->indent <= indent)) - return TRUE; - - if (_xdg_mime_magic_matchlet_compare_level(matchlet->next, - data, - len, - indent + 1)) - return TRUE; - } - - do - { - matchlet = matchlet->next; - } - while (matchlet && matchlet->indent > indent); - } - - return FALSE; -} - -static int -_xdg_mime_magic_match_compare_to_data(XdgMimeMagicMatch *match, - const void *data, - size_t len) -{ - return _xdg_mime_magic_matchlet_compare_level(match->matchlet, data, len, 0); -} - -static void -_xdg_mime_magic_insert_match(XdgMimeMagic *mime_magic, - XdgMimeMagicMatch *match) -{ - XdgMimeMagicMatch *list; - - if (mime_magic->match_list == NULL) - { - mime_magic->match_list = match; - return; - } - - if (match->priority > mime_magic->match_list->priority) - { - match->next = mime_magic->match_list; - mime_magic->match_list = match; - return; - } - - list = mime_magic->match_list; - while (list->next != NULL) - { - if (list->next->priority < match->priority) - { - match->next = list->next; - list->next = match; - return; - } - list = list->next; - } - list->next = match; - match->next = NULL; -} - -XdgMimeMagic * -_xdg_mime_magic_new(void) -{ - return (XdgMimeMagic *)calloc(1, sizeof(XdgMimeMagic)); -} - -void -_xdg_mime_magic_free(XdgMimeMagic *mime_magic) -{ - if (mime_magic) - { - _xdg_mime_magic_match_free(mime_magic->match_list); - free(mime_magic); - } -} - -int -_xdg_mime_magic_get_buffer_extents(XdgMimeMagic *mime_magic) -{ - return mime_magic->max_extent; -} - -const char * -_xdg_mime_magic_lookup_data(XdgMimeMagic *mime_magic, - const void *data, - size_t len) -{ - XdgMimeMagicMatch *match; - - for (match = mime_magic->match_list; match; match = match->next) - { - if (_xdg_mime_magic_match_compare_to_data(match, data, len)) - { - return match->mime_type; - } - } - - return NULL; -} - -static void -_xdg_mime_update_mime_magic_extents(XdgMimeMagic *mime_magic) -{ - XdgMimeMagicMatch *match; - int max_extent = 0; - - for (match = mime_magic->match_list; match; match = match->next) - { - XdgMimeMagicMatchlet *matchlet; - - for (matchlet = match->matchlet; matchlet; matchlet = matchlet->next) - { - int extent; - - extent = matchlet->value_length + matchlet->offset + matchlet->range_length; - if (max_extent < extent) - max_extent = extent; - } - } - - mime_magic->max_extent = max_extent; -} - -static XdgMimeMagicMatchlet * -_xdg_mime_magic_matchlet_mirror(XdgMimeMagicMatchlet *matchlets) -{ - XdgMimeMagicMatchlet *new_list; - XdgMimeMagicMatchlet *tmp; - - if ((matchlets == NULL) || (matchlets->next == NULL)) - return matchlets; - - new_list = NULL; - tmp = matchlets; - while (tmp != NULL) - { - XdgMimeMagicMatchlet *matchlet; - - matchlet = tmp; - tmp = tmp->next; - matchlet->next = new_list; - new_list = matchlet; - } - - return new_list; - -} - -static void -_xdg_mime_magic_read_magic_file(XdgMimeMagic *mime_magic, - FILE *magic_file) -{ - XdgMimeMagicState state; - XdgMimeMagicMatch *match = NULL; /* Quiet compiler */ - - state = XDG_MIME_MAGIC_SECTION; - - while (state != XDG_MIME_MAGIC_EOF) - { - switch (state) - { - case XDG_MIME_MAGIC_SECTION: - match = _xdg_mime_magic_match_new(); - state = _xdg_mime_magic_parse_header(magic_file, match); - if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) - _xdg_mime_magic_match_free(match); - break; - case XDG_MIME_MAGIC_MAGIC: - state = _xdg_mime_magic_parse_magic_line(magic_file, match); - if (state == XDG_MIME_MAGIC_SECTION || - (state == XDG_MIME_MAGIC_EOF && match->mime_type)) - { - match->matchlet = _xdg_mime_magic_matchlet_mirror(match->matchlet); - _xdg_mime_magic_insert_match(mime_magic, match); - } - else if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) - _xdg_mime_magic_match_free(match); - break; - case XDG_MIME_MAGIC_ERROR: - state = _xdg_mime_magic_parse_error(magic_file); - break; - case XDG_MIME_MAGIC_EOF: - default: - /* Make the compiler happy */ - assert(0); - } - } - _xdg_mime_update_mime_magic_extents(mime_magic); -} - -void -_xdg_mime_magic_read_from_file(XdgMimeMagic *mime_magic, - const char *file_name) -{ - FILE *magic_file; - char header[12]; - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - magic_file = fopen(file_name, "r"); - - if (magic_file == NULL) - return; - - if (fread(header, 1, 12, magic_file) == 12) - { - if (memcmp("MIME-Magic\0\n", header, 12) == 0) - _xdg_mime_magic_read_magic_file(mime_magic, magic_file); - } - - fclose(magic_file); -} diff --git a/xdgmimemagic.h b/xdgmimemagic.h deleted file mode 100644 index 1a747583..00000000 --- a/xdgmimemagic.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimemagic.h: Private file. Datastructure for storing the magic files. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2003 Jonathan Blandford - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XDG_MIME_MAGIC_H__ -#define __XDG_MIME_MAGIC_H__ - -#include -#include "xdgmime.h" -typedef struct XdgMimeMagic XdgMimeMagic; - -#ifdef XDG_PREFIX -#define _xdg_mime_glob_read_from_file XDG_ENTRY(glob_read_from_file) -#define _xdg_mime_magic_new XDG_ENTRY(magic_new) -#define _xdg_mime_magic_read_from_file XDG_ENTRY(magic_read_from_file) -#define _xdg_mime_magic_free XDG_ENTRY(magic_free) -#define _xdg_mime_magic_get_buffer_extents XDG_ENTRY(magic_get_buffer_extents) -#define _xdg_mime_magic_lookup_data XDG_ENTRY(magic_lookup_data) -#endif - - -XdgMimeMagic *_xdg_mime_magic_new(void); -void _xdg_mime_magic_read_from_file(XdgMimeMagic *mime_magic, - const char *file_name); -void _xdg_mime_magic_free(XdgMimeMagic *mime_magic); -int _xdg_mime_magic_get_buffer_extents(XdgMimeMagic *mime_magic); -const char *_xdg_mime_magic_lookup_data(XdgMimeMagic *mime_magic, - const void *data, - size_t len); - -#endif /* __XDG_MIME_MAGIC_H__ */ diff --git a/xdgmimeparent.cpp b/xdgmimeparent.cpp deleted file mode 100644 index d0fa617d..00000000 --- a/xdgmimeparent.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimealias.c: Private file. Datastructure for storing the hierarchy. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 2004 Matthias Clasen - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xdgmimeparent.h" -#include "xdgmimeint.h" -#include -#include -#include -#include -#include - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef struct XdgMimeParents XdgMimeParents; - -struct XdgMimeParents -{ - char *mime; - char **parents; - int n_parents; -}; - -struct XdgParentList -{ - struct XdgMimeParents *parents; - int n_mimes; -}; - -XdgParentList * -_xdg_mime_parent_list_new(void) -{ - XdgParentList *list; - - list = (XdgParentList *)malloc(sizeof(XdgParentList)); - - list->parents = NULL; - list->n_mimes = 0; - - return list; -} - -void -_xdg_mime_parent_list_free(XdgParentList *list) -{ - int i; - char **p; - - if (list->parents) - { - for (i = 0; i < list->n_mimes; i++) - { - for (p = list->parents[i].parents; *p; p++) - free(*p); - - free(list->parents[i].parents); - free(list->parents[i].mime); - } - free(list->parents); - } - free(list); -} - -static int -parent_entry_cmp(const void *v1, const void *v2) -{ - return strcmp(((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime); -} - -const char ** -_xdg_mime_parent_list_lookup(XdgParentList *list, - const char *mime) -{ - XdgMimeParents *entry; - XdgMimeParents key; - - if (list->n_mimes > 0) - { - key.mime = (char *)mime; - key.parents = NULL; - - entry = (XdgMimeParents *)bsearch(&key, list->parents, list->n_mimes, - sizeof(XdgMimeParents), &parent_entry_cmp); - if (entry) - return (const char **)entry->parents; - } - - return NULL; -} - -void -_xdg_mime_parent_read_from_file(XdgParentList *list, - const char *file_name) -{ - FILE *file; - char line[255]; - int i, alloc; - XdgMimeParents *entry; - - /* OK to not use CLO_EXEC here because mimedb is single threaded */ - file = fopen(file_name, "r"); - - if (file == NULL) - return; - - /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. - * Blah */ - alloc = list->n_mimes + 16; - list->parents = (XdgMimeParents *)realloc(list->parents, alloc * sizeof(XdgMimeParents)); - while (fgets(line, 255, file) != NULL) - { - char *sep; - if (line[0] == '#') - continue; - - sep = strchr(line, ' '); - if (sep == NULL) - continue; - *(sep++) = '\000'; - sep[strlen(sep) -1] = '\000'; - entry = NULL; - for (i = 0; i < list->n_mimes; i++) - { - if (strcmp(list->parents[i].mime, line) == 0) - { - entry = &(list->parents[i]); - break; - } - } - - if (!entry) - { - if (list->n_mimes == alloc) - { - alloc <<= 1; - list->parents = (XdgMimeParents *)realloc(list->parents, - alloc * sizeof(XdgMimeParents)); - } - list->parents[list->n_mimes].mime = strdup(line); - list->parents[list->n_mimes].parents = NULL; - entry = &(list->parents[list->n_mimes]); - list->n_mimes++; - } - - if (!entry->parents) - { - entry->n_parents = 1; - entry->parents = (char **)malloc((entry->n_parents + 1) * sizeof(char *)); - } - else - { - entry->n_parents += 1; - entry->parents = (char **)realloc(entry->parents, - (entry->n_parents + 2) * sizeof(char *)); - } - entry->parents[entry->n_parents - 1] = strdup(sep); - entry->parents[entry->n_parents] = NULL; - } - - list->parents = (XdgMimeParents *)realloc(list->parents, - list->n_mimes * sizeof(XdgMimeParents)); - - fclose(file); - - if (list->n_mimes > 1) - qsort(list->parents, list->n_mimes, - sizeof(XdgMimeParents), &parent_entry_cmp); -} - - -void -_xdg_mime_parent_list_dump(XdgParentList *list) -{ - int i; - char **p; - - if (list->parents) - { - for (i = 0; i < list->n_mimes; i++) - { - for (p = list->parents[i].parents; *p; p++) - printf("%s %s\n", list->parents[i].mime, *p); - } - } -} - - diff --git a/xdgmimeparent.h b/xdgmimeparent.h deleted file mode 100644 index ca6e8526..00000000 --- a/xdgmimeparent.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* xdgmimeparent.h: Private file. Datastructure for storing the hierarchy. - * - * More info can be found at http://www.freedesktop.org/standards/ - * - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 200 Matthias Clasen - * - * Licensed under the Academic Free License version 2.0 - * Or under the following terms: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XDG_MIME_PARENT_H__ -#define __XDG_MIME_PARENT_H__ - -#include "xdgmime.h" - -typedef struct XdgParentList XdgParentList; - -#ifdef XDG_PREFIX -#define _xdg_mime_parent_read_from_file XDG_ENTRY(parent_read_from_file) -#define _xdg_mime_parent_list_new XDG_ENTRY(parent_list_new) -#define _xdg_mime_parent_list_free XDG_ENTRY(parent_list_free) -#define _xdg_mime_parent_list_lookup XDG_ENTRY(parent_list_lookup) -#endif - -void _xdg_mime_parent_read_from_file(XdgParentList *list, - const char *file_name); -XdgParentList *_xdg_mime_parent_list_new(void); -void _xdg_mime_parent_list_free(XdgParentList *list); -const char **_xdg_mime_parent_list_lookup(XdgParentList *list, - const char *mime); -void _xdg_mime_parent_list_dump(XdgParentList *list); - -#endif /* __XDG_MIME_PARENT_H__ */ -- cgit v1.2.3