/
githubmirror
/
libmodulemd
Обзор
Документация
Войти
/
githubmirror
/
libmodulemd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
libmodulemd-2.9.4
modulemd/modulemd-compression.c
308 строк
8 KB
Stephen Gallagher
Use the new error enums everywhere
05 фев 2020, 03:13
Не верифицирован
05 фев 2020, 03:13
8ff9c0c
Код
Авторство
О чём код?
/* * This file is part of libmodulemd * Copyright (C) 2019 Red Hat, Inc. * * Fedora-License-Identifier: MIT * SPDX-2.0-License-Identifier: MIT * SPDX-3.0-License-Identifier: MIT * * This program is free software. * For more information on the license, see COPYING. * For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>. */ #include <errno.h> #include <fcntl.h> #include <glib.h> #include <inttypes.h> #include <unistd.h> #ifdef HAVE_RPMIO #include <rpm/rpmio.h> #endif #include "modulemd-compression.h" #include "modulemd-errors.h" #include "private/modulemd-compression-private.h" #include "private/modulemd-util.h" #ifdef HAVE_LIBMAGIC #include <magic.h> G_DEFINE_AUTO_CLEANUP_FREE_FUNC (magic_t, magic_close, NULL) #endif ModulemdCompressionTypeEnum modulemd_detect_compression (const gchar *filename, int fd, GError **error) { ModulemdCompressionTypeEnum type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; g_return_val_if_fail (filename, MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED); g_return_val_if_fail (!error || *error == NULL, MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED); if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_FILE_ACCESS, "File %s does not exist or is not a regular file", filename); return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; } /* If the filename has a known suffix, assume it is accurate */ if (g_str_has_suffix (filename, ".gz") || g_str_has_suffix (filename, ".gzip") || g_str_has_suffix (filename, ".gunzip")) { return MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; } if (g_str_has_suffix (filename, ".bz2") || g_str_has_suffix (filename, ".bzip2")) { return MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; } if (g_str_has_suffix (filename, ".xz")) { return MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; } if (g_str_has_suffix (filename, ".yaml") || g_str_has_suffix (filename, ".yml") || g_str_has_suffix (filename, ".txt")) { return MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION; } #ifdef HAVE_LIBMAGIC /* No known suffix? Try using libmagic from file-utils */ const char *mime_type; g_auto (magic_t) magic = NULL; int magic_fd = fcntl (fd, F_DUPFD_CLOEXEC, 0); int err = errno; if (magic_fd < 0) { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_MAGIC, "Could not dup() the file descriptor: %s", g_strerror (err)); return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; } magic = magic_open (MAGIC_MIME); if (magic == NULL) { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_MAGIC, "magic_open() failed: Cannot allocate the magic cookie"); close (magic_fd); return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; } if (magic_load (magic, NULL) == -1) { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_MAGIC, "magic_load() failed: %s", magic_error (magic)); close (magic_fd); return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; } mime_type = magic_descriptor (magic, magic_fd); close (magic_fd); /* Reset the file descriptor to the start of the file, if it has moved */ lseek (fd, 0, SEEK_SET); if (mime_type) { g_debug ( "%s: Detected mime type: %s (%s)", __func__, mime_type, filename); if (g_str_has_prefix (mime_type, "application/x-gzip") || g_str_has_prefix (mime_type, "application/gzip") || g_str_has_prefix (mime_type, "application/gzip-compressed") || g_str_has_prefix (mime_type, "application/gzipped") || g_str_has_prefix (mime_type, "application/x-gzip-compressed") || g_str_has_prefix (mime_type, "application/x-compress") || g_str_has_prefix (mime_type, "application/x-gzip") || g_str_has_prefix (mime_type, "application/x-gunzip") || g_str_has_prefix (mime_type, "multipart/x-gzip")) { type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; } else if (g_str_has_prefix (mime_type, "application/x-bzip2") || g_str_has_prefix (mime_type, "application/x-bz2") || g_str_has_prefix (mime_type, "application/bzip2") || g_str_has_prefix (mime_type, "application/bz2")) { type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; } else if (g_str_has_prefix (mime_type, "application/x-xz")) { type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; } else if (g_str_has_prefix (mime_type, "text/plain") || g_str_has_prefix (mime_type, "text/x-yaml") || g_str_has_prefix (mime_type, "application/x-yaml")) { type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION; } } else { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_MAGIC, "mime_type() detection failed: %s", magic_error (magic)); return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; } /* Reset the file descriptor to the start of the file, if it has moved */ lseek (fd, 0, SEEK_SET); #endif /* HAVE_LIBMAGIC */ return type; } ModulemdCompressionTypeEnum modulemd_compression_type (const gchar *name) { if (!name) { return MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; } int type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; if (!g_strcmp0 (name, "gz") || !g_strcmp0 (name, "gzip") || !g_strcmp0 (name, "gunzip")) { type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; } if (!g_strcmp0 (name, "bz2") || !g_strcmp0 (name, "bzip2")) { type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; } if (!g_strcmp0 (name, "xz")) { type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; } if (!g_strcmp0 (name, "zck")) { type = MODULEMD_COMPRESSION_TYPE_ZCK_COMPRESSION; } return type; } const gchar * modulemd_compression_suffix (ModulemdCompressionTypeEnum comtype) { switch (comtype) { case MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION: return ".gz"; case MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION: return ".bz2"; case MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION: return ".xz"; default: return NULL; } } static const gchar * get_comtype_string (ModulemdCompressionTypeEnum comtype) { /* see rpmio/rpmio.c in the RPM sources for the origin of these * magic strings. */ switch (comtype) { case MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION: return "fdio"; break; case MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION: return "gzdio"; break; case MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION: return "bzdio"; break; case MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION: return "xzdio"; break; default: g_info ("Unknown compression type: %d", comtype); return NULL; break; } } gchar * modulemd_get_rpmio_fmode (const gchar *mode, ModulemdCompressionTypeEnum comtype) { const gchar *type_string; if (!mode) { return NULL; } type_string = get_comtype_string (comtype); if (type_string == NULL) { return NULL; } return g_strdup_printf ("%s.%s", mode, type_string); } #ifdef HAVE_RPMIO gint compressed_stream_read_fn (void *data, unsigned char *buffer, size_t size, size_t *size_read) { FD_t rpmio_fd = (FD_t)data; ssize_t read = Fread (buffer, sizeof (*buffer), size, rpmio_fd); if (read < 0) { g_warning ("Got error [%d] reading the file", Ferror (rpmio_fd)); return 0; } *size_read = read; return 1; } #else gint compressed_stream_read_fn (void *data, unsigned char *buffer, size_t size, size_t *size_read) { /* Not implemented without librpm available */ return 0; } #endif #ifdef HAVE_RPMIO void mmd_Fclose (FD_t fd) { Fclose (fd); } #endif