summaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_subr/magic.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_subr/magic.c')
-rw-r--r--subversion/libsvn_subr/magic.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/subversion/libsvn_subr/magic.c b/subversion/libsvn_subr/magic.c
new file mode 100644
index 0000000..812a263
--- /dev/null
+++ b/subversion/libsvn_subr/magic.c
@@ -0,0 +1,161 @@
+/*
+ * magic.c: wrappers around libmagic
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+/*** Includes. ***/
+
+#include <apr_lib.h>
+#include <apr_file_info.h>
+
+#include "svn_io.h"
+#include "svn_types.h"
+#include "svn_pools.h"
+#include "svn_error.h"
+
+#include "svn_private_config.h"
+
+#include "private/svn_magic.h"
+
+#ifdef SVN_HAVE_LIBMAGIC
+#include <magic.h>
+#endif
+
+struct svn_magic__cookie_t {
+#ifdef SVN_HAVE_LIBMAGIC
+ magic_t magic;
+#else
+ char dummy;
+#endif
+};
+
+#ifdef SVN_HAVE_LIBMAGIC
+/* Close the magic database. */
+static apr_status_t
+close_magic_cookie(void *baton)
+{
+ svn_magic__cookie_t *mc = (svn_magic__cookie_t*)baton;
+ magic_close(mc->magic);
+ return APR_SUCCESS;
+}
+#endif
+
+void
+svn_magic__init(svn_magic__cookie_t **magic_cookie,
+ apr_pool_t *result_pool)
+{
+
+ svn_magic__cookie_t *mc = NULL;
+
+#ifdef SVN_HAVE_LIBMAGIC
+ mc = apr_palloc(result_pool, sizeof(*mc));
+
+ /* Initialise libmagic. */
+#ifndef MAGIC_MIME_TYPE
+ /* Some old versions of libmagic don't support MAGIC_MIME_TYPE.
+ * We can use MAGIC_MIME instead. It returns more than we need
+ * but we can work around that (see below). */
+ mc->magic = magic_open(MAGIC_MIME | MAGIC_ERROR);
+#else
+ mc->magic = magic_open(MAGIC_MIME_TYPE | MAGIC_ERROR);
+#endif
+ if (mc->magic)
+ {
+ /* This loads the default magic database.
+ * Point the MAGIC environment variable at your favourite .mgc
+ * file to load a non-default database. */
+ if (magic_load(mc->magic, NULL) == -1)
+ {
+ magic_close(mc->magic);
+ mc = NULL;
+ }
+ else
+ apr_pool_cleanup_register(result_pool, mc, close_magic_cookie,
+ apr_pool_cleanup_null);
+ }
+#endif
+
+ *magic_cookie = mc;
+}
+
+svn_error_t *
+svn_magic__detect_binary_mimetype(const char **mimetype,
+ const char *local_abspath,
+ svn_magic__cookie_t *magic_cookie,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *magic_mimetype = NULL;
+#ifdef SVN_HAVE_LIBMAGIC
+ apr_finfo_t finfo;
+
+ /* Do not ask libmagic for the mime-types of empty files.
+ * This prevents mime-types like "application/x-empty" from making
+ * Subversion treat empty files as binary. */
+ SVN_ERR(svn_io_stat(&finfo, local_abspath, APR_FINFO_SIZE, scratch_pool));
+ if (finfo.size > 0)
+ {
+ magic_mimetype = magic_file(magic_cookie->magic, local_abspath);
+ if (magic_mimetype)
+ {
+ /* Only return binary mime-types. */
+ if (strncmp(magic_mimetype, "text/", 5) == 0)
+ magic_mimetype = NULL;
+ else
+ {
+ svn_error_t *err;
+#ifndef MAGIC_MIME_TYPE
+ char *p;
+
+ /* Strip off trailing stuff like " charset=ascii". */
+ p = strchr(magic_mimetype, ' ');
+ if (p)
+ *p = '\0';
+#endif
+ /* Make sure we got a valid mime type. */
+ err = svn_mime_type_validate(magic_mimetype, scratch_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_BAD_MIME_TYPE)
+ {
+ svn_error_clear(err);
+ magic_mimetype = NULL;
+ }
+ else
+ return svn_error_trace(err);
+ }
+ else
+ {
+ /* The string is allocated from memory managed by libmagic
+ * so we must copy it to the result pool. */
+ magic_mimetype = apr_pstrdup(result_pool, magic_mimetype);
+ }
+ }
+ }
+ }
+#endif
+
+ *mimetype = magic_mimetype;
+ return SVN_NO_ERROR;
+}
OpenPOWER on IntegriCloud