From 7189ac90b2c5cf57522321cd6663a3a5cf99e57f Mon Sep 17 00:00:00 2001 From: WangFengTu Date: Mon, 13 Jul 2020 15:26:39 +0800 Subject: [PATCH] support gzip a file and unzip a gnu ziped file Signed-off-by: WangFengTu --- src/utils/tar/util_gzip.c | 159 ++++++++++++++++++++++++++++++++++++++ src/utils/tar/util_gzip.h | 32 ++++++++ 2 files changed, 191 insertions(+) create mode 100644 src/utils/tar/util_gzip.c create mode 100644 src/utils/tar/util_gzip.h diff --git a/src/utils/tar/util_gzip.c b/src/utils/tar/util_gzip.c new file mode 100644 index 0000000..3688af4 --- /dev/null +++ b/src/utils/tar/util_gzip.c @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: wangfengtu + * Create: 2020-07-13 + * Description: provide tar functions + ********************************************************************************/ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include + +#include "utils.h" +#include "util_gzip.h" +#include "isula_libutils/log.h" +#include "utils_file.h" + +#define BLKSIZE 32768 + +// Compress +int util_gzip_z(const char *srcfile, const char *dstfile, const mode_t mode) +{ + int ret = 0; + int srcfd = 0; + gzFile stream = NULL; + ssize_t size = 0; + size_t n = 0; + void *buffer = 0; + const char *gzerr = NULL; + int errnum = 0; + + srcfd = util_open(srcfile, O_RDONLY, mode); + if (srcfd < 0) { + ERROR("Open src file: %s, failed: %s", srcfile, strerror(errno)); + return -1; + } + + stream = gzopen(dstfile, "w"); + if (stream == NULL) { + ERROR("gzopen error: %s", strerror(errno)); + close(srcfd); + return -1; + } + + buffer = util_common_calloc_s(BLKSIZE); + if (buffer == NULL) { + ERROR("out of memory"); + ret = -1; + goto out; + } + + while (true) { + size = util_read_nointr(srcfd, buffer, BLKSIZE); + if (size < 0) { + ERROR("read file %s failed: %s", srcfile, strerror(errno)); + ret = -1; + break; + } else if (size == 0) { + break; + } + + n = gzwrite(stream, buffer, size); + if (n <= 0 || n != (size_t)size) { + gzerr = gzerror(stream, &errnum); + if (gzerr != NULL && strcmp(gzerr, "") != 0) { + ERROR("gzread error: %s", gzerr); + } + ret = -1; + break; + } + } + +out: + gzclose(stream); + close(srcfd); + free(buffer); + if (ret != 0) { + if (util_path_remove(dstfile) != 0) { + ERROR("Remove file %s failed: %s", dstfile, strerror(errno)); + } + } + + return ret; +} + +// Decompress +int util_gzip_d(const char *srcfile, const char *dstfile, const mode_t mode) +{ + gzFile stream = NULL; + int dstfd = 0; + const char *gzerr = NULL; + int errnum = 0; + int ret = 0; + ssize_t size = 0; + void *buffer = NULL; + size_t n = 0; + + stream = gzopen(srcfile, "r"); + if (stream == NULL) { + ERROR("gzopen error: %s", strerror(errno)); + return -1; + } + + dstfd = util_open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, mode); + if (dstfd < 0) { + ERROR("Creat file: %s failed: %s", dstfile, strerror(errno)); + gzclose(stream); + return -1; + } + + buffer = util_common_calloc_s(BLKSIZE); + if (buffer == NULL) { + ERROR("out of memory"); + ret = -1; + goto out; + } + + while (true) { + n = gzread(stream, buffer, BLKSIZE); + if (n <= 0) { + gzerr = gzerror(stream, &errnum); + if (gzerr != NULL && strcmp(gzerr, "") != 0) { + ERROR("gzread error: %s", gzerr); + ret = -1; + } + break; + } + + if (n > 0) { + size = util_write_nointr(dstfd, buffer, n); + if (size < 0 || ((size_t)size) != n) { + ret = -1; + ERROR("Write file failed: %s", strerror(errno)); + break; + } + } + + if (gzeof(stream)) { + break; + } + } + +out: + gzclose(stream); + close(dstfd); + free(buffer); + if (ret != 0) { + if (util_path_remove(dstfile) != 0) { + ERROR("Remove file %s failed: %s", dstfile, strerror(errno)); + } + } + + return ret; +} diff --git a/src/utils/tar/util_gzip.h b/src/utils/tar/util_gzip.h new file mode 100644 index 0000000..7a96e11 --- /dev/null +++ b/src/utils/tar/util_gzip.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: wangfengtu + * Create: 2020-07-13 + * Description: provide tar function definition + *********************************************************************************/ +#ifndef UTILS_TAR_UTIL_GZIP_H +#define UTILS_TAR_UTIL_GZIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Compress +int util_gzip_z(const char *srcfile, const char *dstfile, const mode_t mode); + +// Decompress +int util_gzip_d(const char *srcfile, const char *dstfile, const mode_t mode); + +#ifdef __cplusplus +} +#endif + +#endif -- GitLab