diff --git a/.gitignore b/.gitignore index b822519f9..13d5ce326 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 47425dd68..d12875a58 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 c896d33d3..9717b4a7a 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 @@ -563,6 +554,16 @@ check-legacy-binaries: echo "An outdated set_color from a previous fish install was found. You should remove it with:";\ echo " rm '$$SETCOLOR_LOC'";\ fi; + @MIMEDB_LOC=$(prefix)/bin/mimedb;\ + if test -x "$$MIMEDB_LOC" && $$MIMEDB_LOC --version 2>&1 | grep -q "^mimedb, version "; then\ + echo "An outdated mimedb binary from a prevoius fish install was found. You should remove it with:";\ + echo " rm '$$MIMEDB_LOC'";\ + fi; + @FISHD_LOC=$(prefix)/bin/fishd;\ + if test -x "$$FISHD_LOC" && $$FISHD_LOC --version 2>&1 | grep -q "^fishd: fishd, version "; then\ + echo "An outdated fishd binary from a prevoius fish install was found. You should remove it with:";\ + echo " rm '$$FISHD_LOC'";\ + fi; @true; .PHONY: check-legacy-binaries @@ -776,14 +777,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 +947,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 +1006,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/control b/debian/control index 68f7aad22..031dbf460 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,7 @@ Vcs-Browser: https://github.com/fish-shell/fish-shell Package: fish Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, passwd (>= 4.0.3-10), bc, gettext-base, man-db -Recommends: python (>=2.6), xsel (>=1.2.0) +Recommends: python (>=2.6), xsel (>=1.2.0), xdg-utils Description: friendly interactive shell Fish is a command-line shell for modern systems, focusing on user-friendliness, sensibility and discoverability in interactive use. The syntax is simple, but diff --git a/debian/copyright b/debian/copyright index db2a6dcfd..675ae0959 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 75e4bb74f..03d1983f0 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/index.hdr.in b/doc_src/index.hdr.in index b0ddb50f9..55a262600 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -362,7 +362,7 @@ Functions beginning with the string `__fish_print_` print a newline separated li - `__fish_complete_pids` prints a list of all processes IDs with the command name as description. -- `__fish_complete_suffix SUFFIX` performs file completion allowing only files ending in SUFFIX. The mimetype database is used to find a suitable description. +- `__fish_complete_suffix SUFFIX` performs file completion allowing only files ending in SUFFIX, with an optional description. - `__fish_complete_users` prints a list of all users with their full name as description. diff --git a/doc_src/license.hdr b/doc_src/license.hdr index fff8084ec..b9d5fc8c9 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 197474440..000000000 --- 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/doc_src/open.txt b/doc_src/open.txt index 85e91e729..c81c3c9a1 100644 --- a/doc_src/open.txt +++ b/doc_src/open.txt @@ -7,7 +7,7 @@ open FILES... \subsection open-description Description -`open` opens a file in its default application, using the `xdg-open` command if it exists, or else the mimedb command. +`open` opens a file in its default application, using the appropriate tool for the operating system. On GNU/Linux, this requires the common but optional `xdg-open` utility, from the `xdg-utils` package. \subsection open-example Example diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 7b0982d5e..9fac7d80a 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 bbc29227f..000000000 --- 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 1aa1895a9..000000000 --- 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/__fish_complete_mime.fish b/share/functions/__fish_complete_mime.fish deleted file mode 100644 index 3639d31e6..000000000 --- a/share/functions/__fish_complete_mime.fish +++ /dev/null @@ -1,27 +0,0 @@ - -function __fish_complete_mime -d "Complete using text files" - # Find all possible file completions - set -l all - set -l comp (commandline -ct) - set -l base (echo $comp | sed -e 's/\.[a-zA-Z0-9]*$//') - set -l mimetype $argv[1] - eval "set all $base*" - - # Select text files only - set -l files (__fish_filter_mime $mimetype $all) - - # Get descriptions for files - set desc (mimedb -d $files) - - # Format completions and descriptions - if count $files > /dev/null - set -l res - for i in (seq (count $files)) - set res $res $files[$i]\t$desc[$i] - end - - if test $res[1] - printf "%s\n" $res - end - end -end diff --git a/share/functions/__fish_complete_suffix.fish b/share/functions/__fish_complete_suffix.fish index 1f3207063..d0c264db2 100644 --- a/share/functions/__fish_complete_suffix.fish +++ b/share/functions/__fish_complete_suffix.fish @@ -1,6 +1,6 @@ # # Find files that complete $argv[1], has the suffix $argv[2], and -# output them as completions with the description $argv[3] Both +# output them as completions with the optional description $argv[3] Both # $argv[1] and $argv[3] are optional, if only one is specified, it is # assumed to be the argument to complete. # @@ -19,12 +19,12 @@ function __fish_complete_suffix -d "Complete using files" case 1 set comp (commandline -ct) set suff $argv - set desc (mimedb -d $suff) + set desc "" case 2 set comp $argv[1] set suff $argv[2] - set desc (mimedb -d $suff) + set desc "" case 3 set comp $argv[1] @@ -45,8 +45,9 @@ function __fish_complete_suffix -d "Complete using files" # # Also do directory completion, since there might be files # with the correct suffix in a subdirectory + # No need to describe directories (#279) # - __fish_complete_directories $comp + __fish_complete_directories $comp "" end diff --git a/share/functions/__fish_filter_mime.fish b/share/functions/__fish_filter_mime.fish deleted file mode 100644 index f04332d6c..000000000 --- a/share/functions/__fish_filter_mime.fish +++ /dev/null @@ -1,26 +0,0 @@ -# -# $argv[1] is a mimetype. The mimetype may contain wildcards. All -# following arguments are filenames. Filenames matching the mimetype -# are returned. -# - -function __fish_filter_mime -d "Select files with a specific mimetype" - - set -l mime_search $argv[1] - set -e argv[1] - - if not set -l mime (mimedb -f $argv) - return 1 - end - - if count $mime > /dev/null - set -l res - for i in (seq (count $mime)) - switch $mime[$i] - case $mime_search - set res $res $argv[$i] - end - end - printf "%s\n" $res - end -end diff --git a/share/functions/mimedb.fish b/share/functions/mimedb.fish deleted file mode 100644 index 3ed24c22e..000000000 --- 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/share/functions/open.fish b/share/functions/open.fish index 7a1e7bcec..7a9b1e397 100644 --- a/share/functions/open.fish +++ b/share/functions/open.fish @@ -23,7 +23,7 @@ if not test (uname) = Darwin xdg-open $i end else - mimedb -l -- $argv + echo (_ 'No open utility found. Try installing "xdg-open" or "xdg-utils".') end end end diff --git a/wildcard.cpp b/wildcard.cpp index 3b7736bc6..24769e807 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -47,11 +47,6 @@ wildcards using **. */ #define MAX_FILE_LENGTH 1024 -/** - The command to run to get a description from a file suffix -*/ -#define SUFFIX_CMD_STR L"mimedb 2>/dev/null -fd " - /** Description for generic executable */ @@ -382,97 +377,6 @@ static wcstring make_path(const wcstring &base_dir, const wcstring &name) return base_dir + name; } -/** - Return a description of a file based on its suffix. This function - does not perform any caching, it directly calls the mimedb command - to do a lookup. - */ -static wcstring complete_get_desc_suffix_internal(const wcstring &suff) -{ - - wcstring cmd = wcstring(SUFFIX_CMD_STR) + suff; - - wcstring_list_t lst; - wcstring desc; - - if (exec_subshell(cmd, lst, false /* do not apply exit status */) != -1) - { - if (! lst.empty()) - { - const wcstring & ln = lst.at(0); - if (ln.size() > 0 && ln != L"unknown") - { - desc = ln; - /* - I have decided I prefer to have the description - begin in uppercase and the whole universe will just - have to accept it. Hah! - */ - desc[0]=towupper(desc[0]); - } - } - } - - if (desc.empty()) - { - desc = COMPLETE_FILE_DESC; - } - - suffix_map[suff] = desc.c_str(); - return desc; -} - - -/** - Use the mimedb command to look up a description for a given suffix -*/ -static wcstring complete_get_desc_suffix(const wchar_t *suff_orig) -{ - - size_t len; - wchar_t *suff; - wchar_t *pos; - - len = wcslen(suff_orig); - - if (len == 0) - return COMPLETE_FILE_DESC; - - suff = wcsdup(suff_orig); - - /* - Drop characters that are commonly used as backup suffixes from the suffix - */ - for (pos=suff; *pos; pos++) - { - if (wcschr(L"?;#~@&", *pos)) - { - *pos=0; - break; - } - } - - wcstring tmp = escape(suff, ESCAPE_ALL); - free(suff); - suff = wcsdup(tmp.c_str()); - - std::map::iterator iter = suffix_map.find(suff); - wcstring desc; - if (iter != suffix_map.end()) - { - desc = iter->second; - } - else - { - desc = complete_get_desc_suffix_internal(suff); - } - - free(suff); - - return desc; -} - - /** Obtain a description string for the file specified by the filename. @@ -493,7 +397,6 @@ static wcstring file_get_desc(const wcstring &filename, struct stat buf, int err) { - const wchar_t *suffix; if (!lstat_res) { @@ -595,12 +498,6 @@ static wcstring file_get_desc(const wcstring &filename, } } - suffix = wcsrchr(filename.c_str(), L'.'); - if (suffix != 0 && !wcsrchr(suffix, L'/')) - { - return complete_get_desc_suffix(suffix); - } - return COMPLETE_FILE_DESC ; } diff --git a/xdgmime.cpp b/xdgmime.cpp deleted file mode 100644 index 633d0b0a5..000000000 --- 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 9c53bb11a..000000000 --- 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 e556d4e64..000000000 --- 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 13933642d..000000000 --- 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 4182f3c97..000000000 --- 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 136e49a39..000000000 --- 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 7e8ea31ca..000000000 --- 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 5e825dab3..000000000 --- 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 b906685e8..000000000 --- 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 1a747583a..000000000 --- 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 d0fa617dc..000000000 --- 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 ca6e85267..000000000 --- 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__ */